Skip to content

Commit

Permalink
Make ClosureBundler thread-safe by making mutable instance variables …
Browse files Browse the repository at this point in the history
…final

Using mutable instance variables is not thread-safe, and some race conditions have caused sourceMaps to be empty.

This change makes the mutable instance variables final and makes the with*() methods copy-on-write.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=141220397
  • Loading branch information
Dominator008 authored and blickly committed Dec 7, 2016
1 parent e92b350 commit 4f65a57
Showing 1 changed file with 21 additions and 13 deletions.
34 changes: 21 additions & 13 deletions src/com/google/javascript/jscomp/deps/ClosureBundler.java
Expand Up @@ -29,40 +29,48 @@
/** /**
* A utility class to assist in creating JS bundle files. * A utility class to assist in creating JS bundle files.
*/ */
public class ClosureBundler { public final class ClosureBundler {


private final Transpiler transpiler; private final Transpiler transpiler;


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


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


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


public ClosureBundler(Transpiler transpiler) { public ClosureBundler(Transpiler transpiler) {
this(transpiler, EvalMode.NORMAL, null, "unknown_source",
new ConcurrentHashMap<String, String>());
}

private ClosureBundler(Transpiler transpiler, EvalMode mode, String sourceUrl, String path,
Map<String, String> sourceMapCache) {
this.transpiler = transpiler; this.transpiler = transpiler;
this.mode = mode;
this.sourceUrl = sourceUrl;
this.path = path;
this.sourceMapCache = sourceMapCache;
} }


public final ClosureBundler useEval(boolean useEval) { public final ClosureBundler useEval(boolean useEval) {
this.mode = useEval ? EvalMode.EVAL : EvalMode.NORMAL; EvalMode newMode = useEval ? EvalMode.EVAL : EvalMode.NORMAL;
return this; return new ClosureBundler(transpiler, newMode, sourceUrl, path, sourceMapCache);
} }


public final ClosureBundler withSourceUrl(String sourceUrl) { public final ClosureBundler withSourceUrl(String newSourceUrl) {
this.sourceUrl = sourceUrl; return new ClosureBundler(transpiler, mode, newSourceUrl, path, sourceMapCache);
return this;
} }


public final ClosureBundler withPath(String path) { public final ClosureBundler withPath(String newPath) {
this.path = path; return new ClosureBundler(transpiler, mode, sourceUrl, newPath, sourceMapCache);
return this;
} }


/** Append the contents of the string to the supplied appendable. */ /** Append the contents of the string to the supplied appendable. */
Expand Down

0 comments on commit 4f65a57

Please sign in to comment.