# HG changeset patch # User Jaroslav Tulach # Date 1398540606 -7200 # Node ID 4a1398eff4fb1e1d2bf3098a59a57c76ce4d45ad # Parent c572d850079c480042ca613ac60a2fa83dbd1425 Different meaning of root vs. added classes. Ability to explicitly enumerate classes that should be exported and available with fully qualified name. diff -r c572d850079c -r 4a1398eff4fb launcher/http/src/main/java/org/apidesign/bck2brwsr/launcher/CompileCP.java --- a/launcher/http/src/main/java/org/apidesign/bck2brwsr/launcher/CompileCP.java Sat Apr 26 21:16:06 2014 +0200 +++ b/launcher/http/src/main/java/org/apidesign/bck2brwsr/launcher/CompileCP.java Sat Apr 26 21:30:06 2014 +0200 @@ -51,8 +51,8 @@ } Bck2Brwsr.newCompiler() - .addRootClasses(classes.toArray(new String[0])) - .extension(true) + .addClasses(classes.toArray(new String[0])) + .library(true) .resources(new JarRes()) .generate(w); w.flush(); @@ -78,7 +78,7 @@ try { Bck2Brwsr.newCompiler() .addRootClasses(classes.toArray(new String[0])) - .extension(true) + .library(true) .resources(new EmulationResources()) .generate(w); w.flush(); diff -r c572d850079c -r 4a1398eff4fb rt/emul/brwsrtest/src/test/java/org/apidesign/bck2brwsr/brwsrtest/BooleanTest.java --- a/rt/emul/brwsrtest/src/test/java/org/apidesign/bck2brwsr/brwsrtest/BooleanTest.java Sat Apr 26 21:16:06 2014 +0200 +++ b/rt/emul/brwsrtest/src/test/java/org/apidesign/bck2brwsr/brwsrtest/BooleanTest.java Sat Apr 26 21:30:06 2014 +0200 @@ -26,7 +26,6 @@ * * @author Jaroslav Tulach */ -@org.apidesign.bck2brwsr.core.Exported public class BooleanTest { @JavaScriptBody(args = { "tr" }, body = "return tr ? true : false;") private static native Object trueFalse(boolean tr); diff -r c572d850079c -r 4a1398eff4fb rt/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java Sat Apr 26 21:16:06 2014 +0200 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java Sat Apr 26 21:30:06 2014 +0200 @@ -20,6 +20,7 @@ import java.io.IOException; import java.io.InputStream; import java.net.URL; +import org.apidesign.bck2brwsr.core.Exported; /** Build your own virtual machine! Use methods in this class to generate * a skeleton JVM in JavaScript that contains pre-compiled classes of your @@ -54,12 +55,14 @@ */ public final class Bck2Brwsr { private final ObfuscationLevel level; + private final StringArray rootcls; private final StringArray classes; private final Resources res; private final boolean extension; - private Bck2Brwsr(ObfuscationLevel level, StringArray classes, Resources resources, boolean extension) { + private Bck2Brwsr(ObfuscationLevel level, StringArray rootcls, StringArray classes, Resources resources, boolean extension) { this.level = level; + this.rootcls = rootcls; this.classes = classes; this.res = resources; this.extension = extension; @@ -99,26 +102,51 @@ * @since 0.5 */ public static Bck2Brwsr newCompiler() { - return new Bck2Brwsr(ObfuscationLevel.NONE, new StringArray(), null, false); + return new Bck2Brwsr(ObfuscationLevel.NONE, new StringArray(), new StringArray(), null, false); } - /** Creates new instance of the Bck2Brwsr compiler which inherits - * all values from this instance and adds additional classes - * to the list of those that should be compiled by the {@link #generate(java.lang.Appendable)} - * method. + /** Adds additional classes + * to the list of those that should be included in the generated + * JavaScript file. + * These classes are guaranteed to be available in the + * generated virtual machine code accessible using their fully + * qualified name. This brings the same behavior as if the + * classes were added by {@link #addClasses(java.lang.String...) } and + * were annotated with {@link Exported} annotation. * * @param classes the classes to add to the compilation - * @return new instance of the compiler + * @return new instance of the Bck2Brwsr compiler which inherits + * all values from this */ public Bck2Brwsr addRootClasses(String... classes) { if (classes.length == 0) { return this; } else { - return new Bck2Brwsr(level, this.classes.addAndNew(classes), res, + return new Bck2Brwsr(level, rootcls.addAndNew(classes), this.classes, res, extension); } } + /** Adds additional classes + * to the list of those that should be included in the generated + * JavaScript file. These classes are guaranteed to be present, + * but they may not be accessible through their fully qualified + * name. + * + * @param classes the classes to add to the compilation + * @return new instance of the Bck2Brwsr compiler which inherits + * all values from this + * @since 0.9 + */ + public Bck2Brwsr addClasses(String... classes) { + if (classes.length == 0) { + return this; + } else { + return new Bck2Brwsr(level, rootcls, this.classes.addAndNew(classes), res, + extension); + } + } + /** Changes the obfuscation level for the compiler by creating new instance * which inherits all values from this and adjust the level * of obfuscation. @@ -128,7 +156,7 @@ * @since 0.5 */ public Bck2Brwsr obfuscation(ObfuscationLevel level) { - return new Bck2Brwsr(level, classes, res, extension); + return new Bck2Brwsr(level, rootcls, classes, res, extension); } /** A way to change the provider of additional resources (classes) for the @@ -140,11 +168,22 @@ * @since 0.5 */ public Bck2Brwsr resources(Resources res) { - return new Bck2Brwsr(level, classes, res, extension); + return new Bck2Brwsr(level, rootcls, classes, res, extension); } - public Bck2Brwsr extension(boolean extension) { - return new Bck2Brwsr(level, classes, res, extension); + /** Should one generate a library? By default the system generates + * all transitive classes needed by the the transitive closure of + * {@link #addRootClasses(java.lang.String...)} and {@link #addClasses(java.lang.String...)}. + * By turning on the library mode, only classes explicitly listed + * will be included in the archive. The others will be referenced + * as external ones. + * + * @param library turn on the library mode? + * @return new instance of the compiler with library flag changed + * @since 0.9 + */ + public Bck2Brwsr library(boolean library) { + return new Bck2Brwsr(level, rootcls, classes, res, library); } /** A way to change the provider of additional resources (classes) for the @@ -169,7 +208,7 @@ Resources r = res != null ? res : new LdrRsrcs(Bck2Brwsr.class.getClassLoader()); if (level != ObfuscationLevel.NONE) { try { - ClosureWrapper.produceTo(out, level, r, classes, extension); + ClosureWrapper.produceTo(out, level, r, rootcls, classes, extension); return; } catch (IOException ex) { throw ex; @@ -179,7 +218,7 @@ } } - VM.compile(out, r, classes, extension); + VM.compile(out, r, rootcls, classes, extension); } /** Provider of resources (classes and other files). The diff -r c572d850079c -r 4a1398eff4fb rt/vm/src/main/java/org/apidesign/vm4brwsr/ClosureWrapper.java --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ClosureWrapper.java Sat Apr 26 21:16:06 2014 +0200 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ClosureWrapper.java Sat Apr 26 21:30:06 2014 +0200 @@ -38,6 +38,7 @@ private final Bck2Brwsr.Resources res; private final StringArray classes; private final boolean extension; + private final StringArray rootClasses; private String compiledCode; private String externsCode; @@ -45,6 +46,7 @@ private ClosureWrapper(Appendable out, String compilationLevel, Bck2Brwsr.Resources res, + StringArray rootClasses, StringArray classes, boolean extension) { super( @@ -52,6 +54,7 @@ new PrintStream(new APS(out)), System.err ); this.res = res; + this.rootClasses = rootClasses; this.classes = classes; this.extension = extension; } @@ -96,7 +99,7 @@ if (compiledCode == null) { StringBuilder sb = new StringBuilder(); try { - VM.compile(sb, res, classes, extension); + VM.compile(sb, res, rootClasses, classes, extension); compiledCode = sb.toString(); } catch (IOException ex) { compiledCode = ex.getMessage(); @@ -141,6 +144,7 @@ static int produceTo(Appendable output, ObfuscationLevel obfuscationLevel, Bck2Brwsr.Resources resources, + StringArray rootArr, StringArray arr, boolean extension) throws IOException { final ClosureWrapper cw = @@ -148,7 +152,7 @@ (obfuscationLevel == ObfuscationLevel.FULL) ? "ADVANCED_OPTIMIZATIONS" : "SIMPLE_OPTIMIZATIONS", - resources, arr, extension); + resources, rootArr, arr, extension); try { return cw.doRun(); } catch (FlagUsageException ex) { diff -r c572d850079c -r 4a1398eff4fb rt/vm/src/main/java/org/apidesign/vm4brwsr/ExportedSymbols.java --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ExportedSymbols.java Sat Apr 26 21:16:06 2014 +0200 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ExportedSymbols.java Sat Apr 26 21:30:06 2014 +0200 @@ -30,15 +30,20 @@ @ExtraJavaScript(processByteCode = false, resource="") final class ExportedSymbols { private final Bck2Brwsr.Resources resources; + private final StringArray exported; private final Map isMarkedAsExportedCache; - ExportedSymbols(final Bck2Brwsr.Resources resources) { + ExportedSymbols(final Bck2Brwsr.Resources resources, StringArray explicitlyExported) { this.resources = resources; + this.exported = explicitlyExported; isMarkedAsExportedCache = new HashMap(); } boolean isExported(ClassData classData) throws IOException { + if (exported.contains(classData.getClassName())) { + return true; + } return classData.isPublic() && isMarkedAsExportedPackage( classData.getPkgName()) || isMarkedAsExported(classData); diff -r c572d850079c -r 4a1398eff4fb rt/vm/src/main/java/org/apidesign/vm4brwsr/Main.java --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/Main.java Sat Apr 26 21:16:06 2014 +0200 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/Main.java Sat Apr 26 21:30:06 2014 +0200 @@ -105,8 +105,7 @@ } try (Writer w = new BufferedWriter(new FileWriter(gt))) { - Bck2Brwsr.newCompiler(). - extension(createExtension). + Bck2Brwsr.newCompiler().library(createExtension). obfuscation(obfLevel). addRootClasses(classes.toArray()). resources(new LdrRsrcs(mainClassLoader)). diff -r c572d850079c -r 4a1398eff4fb rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Sat Apr 26 21:16:06 2014 +0200 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Sat Apr 26 21:30:06 2014 +0200 @@ -40,11 +40,11 @@ VM.class }; - private VM(Appendable out, Bck2Brwsr.Resources resources) { + private VM(Appendable out, Bck2Brwsr.Resources resources, StringArray explicitlyExported) { super(out); this.resources = resources; this.classDataCache = new ClassDataCache(resources); - this.exportedSymbols = new ExportedSymbols(resources); + this.exportedSymbols = new ExportedSymbols(resources, explicitlyExported); this.invokerMethods = new StringArray(); } @@ -63,9 +63,16 @@ return false; } - static void compile(Appendable out, Bck2Brwsr.Resources l, StringArray names, boolean extension) throws IOException { - VM vm = extension ? new Extension(out, l, names.toArray()) - : new Standalone(out, l); + static void compile(Appendable out, + Bck2Brwsr.Resources l, + StringArray rootNames, + StringArray names, + boolean extension + ) throws IOException { + StringArray both = names.addAndNew(rootNames.toArray()); + + VM vm = extension ? new Extension(out, l, both.toArray(), rootNames) + : new Standalone(out, l, rootNames); final StringArray fixedNames = new StringArray(); @@ -73,7 +80,7 @@ fixedNames.add(fixedClass.getName().replace('.', '/')); } - vm.doCompile(fixedNames.addAndNew(names.toArray())); + vm.doCompile(fixedNames.addAndNew(both.toArray())); } private void doCompile(StringArray names) throws IOException { @@ -412,8 +419,8 @@ } private static final class Standalone extends VM { - private Standalone(Appendable out, Bck2Brwsr.Resources resources) { - super(out, resources); + private Standalone(Appendable out, Bck2Brwsr.Resources resources, StringArray explicitlyExported) { + super(out, resources, explicitlyExported); } @Override @@ -488,8 +495,8 @@ private final StringArray extensionClasses; private Extension(Appendable out, Bck2Brwsr.Resources resources, - String[] extClassesArray) { - super(out, resources); + String[] extClassesArray, StringArray explicitlyExported) { + super(out, resources, explicitlyExported); this.extensionClasses = StringArray.asList(extClassesArray); } diff -r c572d850079c -r 4a1398eff4fb rt/vm/src/test/java/org/apidesign/vm4brwsr/Numbers.java --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/Numbers.java Sat Apr 26 21:16:06 2014 +0200 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/Numbers.java Sat Apr 26 21:30:06 2014 +0200 @@ -26,7 +26,6 @@ * * @author Jaroslav Tulach */ -@org.apidesign.bck2brwsr.core.Exported public class Numbers { private static Double autoboxDbl() { return 3.3; diff -r c572d850079c -r 4a1398eff4fb rt/vm/src/test/java/org/apidesign/vm4brwsr/TestVM.java --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/TestVM.java Sat Apr 26 21:16:06 2014 +0200 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/TestVM.java Sat Apr 26 21:30:06 2014 +0200 @@ -133,8 +133,7 @@ Bck2Brwsr.generate(sb, new EmulationResources()); Bck2Brwsr b2b = Bck2Brwsr.newCompiler(). resources(new EmulationResources()). - addRootClasses(names). - extension(true); + addRootClasses(names).library(true); b2b.generate(sb); ScriptEngineManager sem = new ScriptEngineManager(); ScriptEngine js = sem.getEngineByExtension("js");