Skip to content

Commit

Permalink
Refactor TranspilingClosureBundler into a ClosureBundler and an encap…
Browse files Browse the repository at this point in the history
…sulated Transpiler.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=139596773
  • Loading branch information
shicks authored and blickly committed Nov 19, 2016
1 parent 9df8eea commit 661d04c
Show file tree
Hide file tree
Showing 7 changed files with 194 additions and 409 deletions.
141 changes: 84 additions & 57 deletions src/com/google/javascript/jscomp/deps/ClosureBundler.java
Expand Up @@ -15,27 +15,47 @@
*/
package com.google.javascript.jscomp.deps;

import com.google.common.base.Strings;
import com.google.common.io.CharSource;
import com.google.common.io.Files;

import com.google.javascript.jscomp.transpile.TranspileResult;
import com.google.javascript.jscomp.transpile.Transpiler;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
* A utility class to assist in creating JS bundle files.
*/
public class ClosureBundler {
private boolean useEval = false;

private final Transpiler transpiler;

private EvalMode mode = EvalMode.NORMAL;
private String sourceUrl = null;
private String path = "unknown_source";

// TODO(sdh): This cache should be moved out into a higher level, but is
// currently required due to the API that source maps must be accessible
// via just a path (and not the file contents).
private final Map<String, String> sourceMapCache = new ConcurrentHashMap<>();

// TODO(sdh): This causes serious problems with edit-refresh if the bundler
// is used in the wrong scope. The logic must be moved outside this class.
private boolean shouldSendRuntime = true;

public ClosureBundler() {
this(Transpiler.NULL);
}

public ClosureBundler(Transpiler transpiler) {
this.transpiler = transpiler;
}

public final ClosureBundler useEval(boolean useEval) {
this.useEval = useEval;
this.mode = useEval ? EvalMode.EVAL : EvalMode.NORMAL;
return this;
}

Expand Down Expand Up @@ -78,10 +98,19 @@ public void appendTo(
Appendable out,
DependencyInfo info,
CharSource content) throws IOException {
// TODO(sdh): Move this logic into the bundle manager.
if (shouldSendRuntime) {
String runtime = transpiler.runtime();
if (!runtime.isEmpty()) {
mode.appendTraditional(runtime, out, null);
}
shouldSendRuntime = false;
}

if (info.isModule()) {
appendGoogModule(out, content);
mode.appendGoogModule(transpile(content.read()), out, sourceUrl);
} else {
appendTraditional(out, content);
mode.appendTraditional(transpile(content.read()), out, sourceUrl);
}
}

Expand All @@ -90,44 +119,60 @@ public void appendTo(
* method.
*/
public String getSourceMap(String path) {
return "";
return Strings.nullToEmpty(sourceMapCache.get(path));
}

private void appendTraditional(Appendable out, CharSource contents)
throws IOException {
if (useEval) {
out.append("(0,eval(\"");
append(out, Mode.ESCAPED, contents);
appendSourceUrl(out, Mode.ESCAPED);
out.append("\"));\n");
} else {
append(out, Mode.NORMAL, contents);
appendSourceUrl(out, Mode.NORMAL);
}
private String transpile(String s) {
TranspileResult result = transpiler.transpile(path, s);
sourceMapCache.put(path, result.sourceMap());
return result.transpiled();
}

private void appendGoogModule(Appendable out, CharSource contents)
throws IOException {
if (useEval) {
out.append("goog.loadModule(\"");
append(out, Mode.ESCAPED, contents);
appendSourceUrl(out, Mode.ESCAPED);
out.append("\");\n");
} else {
// add the prefix on the first line so the line numbers aren't affected.
out.append(
"goog.loadModule(function(exports) {"
+ "'use strict';");
append(out, Mode.NORMAL, contents);
out.append(
"\n" // terminate any trailing single line comment.
+ ";" // terminate any trailing expression.
+ "return exports;});\n");
appendSourceUrl(out, Mode.NORMAL);
}
private enum EvalMode {
EVAL {
@Override
void appendTraditional(String s, Appendable out, String sourceUrl) throws IOException {
out.append("(0,eval(\"");
EscapeMode.ESCAPED.append(s, out);
appendSourceUrl(out, EscapeMode.ESCAPED, sourceUrl);
out.append("\"));\n");
}

@Override
void appendGoogModule(String s, Appendable out, String sourceUrl) throws IOException {
out.append("goog.loadModule(\"");
EscapeMode.ESCAPED.append(s, out);
appendSourceUrl(out, EscapeMode.ESCAPED, sourceUrl);
out.append("\");\n");
}
},
NORMAL {
@Override
void appendTraditional(String s, Appendable out, String sourceUrl) throws IOException {
EscapeMode.NORMAL.append(s, out);
appendSourceUrl(out, EscapeMode.NORMAL, sourceUrl);
}

@Override
void appendGoogModule(String s, Appendable out, String sourceUrl) throws IOException {
// add the prefix on the first line so the line numbers aren't affected.
out.append(
"goog.loadModule(function(exports) {"
+ "'use strict';");
EscapeMode.NORMAL.append(s, out);
out.append(
"\n" // terminate any trailing single line comment.
+ ";" // terminate any trailing expression.
+ "return exports;});\n");
appendSourceUrl(out, EscapeMode.NORMAL, sourceUrl);
}
};

abstract void appendTraditional(String s, Appendable out, String sourceUrl) throws IOException;
abstract void appendGoogModule(String s, Appendable out, String sourceUrl) throws IOException;
}

private enum Mode {
private enum EscapeMode {
ESCAPED {
@Override void append(String s, Appendable out) throws IOException {
out.append(SourceCodeEscapers.javascriptEscaper().escape(s));
Expand All @@ -142,17 +187,8 @@ private enum Mode {
abstract void append(String s, Appendable out) throws IOException;
}

private void append(Appendable out, Mode mode, String s) throws IOException {
String transformed = transformInput(s, path);
mode.append(transformed, out);
}

private void append(Appendable out, Mode mode, CharSource cs)
private static void appendSourceUrl(Appendable out, EscapeMode mode, String sourceUrl)
throws IOException {
append(out, mode, cs.read());
}

private void appendSourceUrl(Appendable out, Mode mode) throws IOException {
if (sourceUrl == null) {
return;
}
Expand All @@ -161,13 +197,4 @@ private void appendSourceUrl(Appendable out, Mode mode) throws IOException {
// but source URLs generally aren't valid JS inputs.
mode.append(toAppend, out);
}

/**
* Template method. Subclasses that need to transform the inputs should override this method.
* (For example, {@link TranspilingClosureBundler#transformInput} transpiles inputs from ES6
* to ES5.)
*/
protected String transformInput(String input, String path) {
return input;
}
}
199 changes: 0 additions & 199 deletions src/com/google/javascript/jscomp/deps/TranspilingClosureBundler.java

This file was deleted.

0 comments on commit 661d04c

Please sign in to comment.