Adding javadoc to various obfuscation levels. Disabling MEDIUM for the upcoming merge to default, as it is not finished yet.
2 * Back 2 Browser Bytecode Translator
3 * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 2 of the License.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. Look for COPYING file in the top folder.
16 * If not, see http://opensource.org/licenses/GPL-2.0.
18 package org.apidesign.vm4brwsr;
20 import com.google.javascript.jscomp.CommandLineRunner;
21 import com.google.javascript.jscomp.SourceFile;
22 import java.io.IOException;
23 import java.io.OutputStream;
24 import java.io.PrintStream;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.Collection;
28 import java.util.Collections;
29 import java.util.List;
30 import org.apidesign.bck2brwsr.core.ExtraJavaScript;
31 import org.apidesign.vm4brwsr.ByteCodeParser.ClassData;
32 import org.apidesign.vm4brwsr.ByteCodeParser.FieldData;
33 import org.apidesign.vm4brwsr.ByteCodeParser.MethodData;
37 * @author Jaroslav Tulach <jtulach@netbeans.org>
39 @ExtraJavaScript(processByteCode = false, resource="")
40 final class ClosureWrapper extends CommandLineRunner {
41 private static final String[] ARGS = { "--compilation_level", "SIMPLE_OPTIMIZATIONS", "--js", "bck2brwsr-raw.js" /*, "--debug", "--formatting", "PRETTY_PRINT" */ };
43 private final ClosuresObfuscationDelegate obfuscationDelegate;
44 private final Bck2Brwsr.Resources res;
45 private final StringArray classes;
47 private String compiledCode;
48 private String externsCode;
50 private ClosureWrapper(Appendable out,
51 String compilationLevel,
52 ClosuresObfuscationDelegate obfuscationDelegate,
53 Bck2Brwsr.Resources res, StringArray classes) {
55 generateArguments(compilationLevel),
56 new PrintStream(new APS(out)), System.err
58 this.obfuscationDelegate = obfuscationDelegate;
60 this.classes = classes;
64 protected List<SourceFile> createInputs(List<String> files, boolean allowStdIn) throws FlagUsageException, IOException {
65 if (files.size() != 1 || !"bck2brwsr-raw.js".equals(files.get(0))) {
66 throw new IOException("Unexpected files: " + files);
68 return Collections.nCopies(
70 SourceFile.fromGenerator(
72 new SourceFile.Generator() {
74 public String getCode() {
75 return getCompiledCode();
82 protected List<SourceFile> createExterns()
83 throws FlagUsageException, IOException {
84 final List<SourceFile> externsFiles =
85 new ArrayList<SourceFile>(super.createExterns());
88 SourceFile.fromGenerator(
89 "bck2brwsr_externs.js",
90 new SourceFile.Generator() {
92 public String getCode() {
93 return getExternsCode();
99 private String getCompiledCode() {
100 if (compiledCode == null) {
101 StringBuilder sb = new StringBuilder();
103 VM.compile(res, sb, classes, obfuscationDelegate);
104 compiledCode = sb.toString();
105 } catch (IOException ex) {
106 compiledCode = ex.getMessage();
112 private String getExternsCode() {
113 if (externsCode == null) {
114 // need compiled code at this point
117 final StringBuilder sb = new StringBuilder("function RAW() {};\n");
118 for (final String extern: obfuscationDelegate.getExterns()) {
119 sb.append("RAW.prototype.").append(extern).append(";\n");
121 externsCode = sb.toString();
126 private static final class APS extends OutputStream {
127 private final Appendable out;
129 public APS(Appendable out) {
133 public void write(int b) throws IOException {
138 private static String[] generateArguments(String compilationLevel) {
139 String[] finalArgs = ARGS.clone();
140 finalArgs[1] = compilationLevel;
145 static int produceTo(Appendable w, ObfuscationLevel obfuscationLevel, Bck2Brwsr.Resources resources, StringArray arr) throws IOException {
146 ClosureWrapper cw = create(w, obfuscationLevel, resources, arr);
149 } catch (FlagUsageException ex) {
150 throw new IOException(ex);
154 private static ClosureWrapper create(Appendable w,
155 ObfuscationLevel obfuscationLevel,
156 Bck2Brwsr.Resources resources,
158 switch (obfuscationLevel) {
160 return new ClosureWrapper(w, "SIMPLE_OPTIMIZATIONS",
161 new SimpleObfuscationDelegate(),
165 return new ClosureWrapper(w, "ADVANCED_OPTIMIZATIONS",
166 new MediumObfuscationDelegate(),
170 return new ClosureWrapper(w, "ADVANCED_OPTIMIZATIONS",
171 new FullObfuscationDelegate(),
174 throw new IllegalArgumentException(
175 "Unsupported level: " + obfuscationLevel);
179 private static abstract class ClosuresObfuscationDelegate
180 extends ObfuscationDelegate {
181 public abstract Collection<String> getExterns();
184 private static final class SimpleObfuscationDelegate
185 extends ClosuresObfuscationDelegate {
187 public void exportJSProperty(Appendable out,
189 String propertyName) throws IOException {
193 public void exportClass(Appendable out,
196 ClassData classData) throws IOException {
200 public void exportMethod(Appendable out,
203 MethodData methodData) throws IOException {
207 public void exportField(Appendable out,
210 FieldData fieldData) throws IOException {
214 public Collection<String> getExterns() {
215 return Collections.EMPTY_LIST;
219 private static abstract class AdvancedObfuscationDelegate
220 extends ClosuresObfuscationDelegate {
221 private static final String[] INITIAL_EXTERNS = {
263 "getClass__Ljava_lang_Class_2",
264 "clone__Ljava_lang_Object_2"
267 private final Collection<String> externs;
269 protected AdvancedObfuscationDelegate() {
270 externs = new ArrayList<String>(Arrays.asList(INITIAL_EXTERNS));
274 public void exportClass(Appendable out,
277 ClassData classData) throws IOException {
278 exportJSProperty(out, destObject, mangledName);
282 public void exportMethod(Appendable out,
285 MethodData methodData) throws IOException {
286 if ((methodData.access & ByteCodeParser.ACC_PRIVATE) == 0) {
287 exportJSProperty(out, destObject, mangledName);
292 public void exportField(Appendable out,
295 FieldData fieldData) throws IOException {
296 if ((fieldData.access & ByteCodeParser.ACC_PRIVATE) == 0) {
297 exportJSProperty(out, destObject, mangledName);
302 public Collection<String> getExterns() {
306 protected void addExtern(String extern) {
311 private static final class MediumObfuscationDelegate
312 extends AdvancedObfuscationDelegate {
314 public void exportJSProperty(Appendable out,
316 String propertyName) {
317 addExtern(propertyName);
321 private static final class FullObfuscationDelegate
322 extends AdvancedObfuscationDelegate {
324 public void exportJSProperty(Appendable out,
326 String propertyName) throws IOException {
327 out.append("\n").append(destObject).append("['")
328 .append(propertyName)
330 .append(destObject).append(".").append(propertyName)