Skip to content

Commit

Permalink
Factor out logic for turning a DependencyInfo into a goog.addDependen…
Browse files Browse the repository at this point in the history
…cy() call.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=120767458
  • Loading branch information
shicks authored and blickly committed Apr 26, 2016
1 parent ee66dcd commit fc465c1
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 42 deletions.
58 changes: 58 additions & 0 deletions src/com/google/javascript/jscomp/deps/DependencyInfo.java
Expand Up @@ -16,9 +16,16 @@

package com.google.javascript.jscomp.deps;

import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
* A data structure for JS dependency information for a single .js file.
Expand Down Expand Up @@ -54,4 +61,55 @@ public abstract class Base implements DependencyInfo {
return "goog".equals(getLoadFlags().get("module"));
}
}

/** Utility methods. */
class Util {
private Util() {}

// TODO(sdh): This would be better as a defender method once Java 8 is allowed (b/28382956):
// void DependencyInfo#writeAddDependency(Appendable);
/** Prints a goog.addDependency call for a single DependencyInfo. */
public static void writeAddDependency(Appendable out, DependencyInfo info) throws IOException {
out.append("goog.addDependency('")
.append(info.getPathRelativeToClosureBase())
.append("', ");
writeJsArray(out, info.getProvides());
out.append(", ");
writeJsArray(out, info.getRequires());
Map<String, String> loadFlags = info.getLoadFlags();
if (!loadFlags.isEmpty()) {
out.append(", ");
writeJsObject(out, loadFlags);
}
out.append(");\n");
}

/** Prints a map as a JS object literal. */
private static void writeJsObject(Appendable out, Map<String, String> map) throws IOException {
List<String> entries = new ArrayList<>();
for (Map.Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey().replace("'", "\\'");
String value = entry.getValue().replace("'", "\\'");
entries.add("'" + key + "': '" + value + "'");
}
out.append("{");
out.append(Joiner.on(", ").join(entries));
out.append("}");
}

/** Prints a list of strings formatted as a JavaScript array of string literals. */
private static void writeJsArray(Appendable out, Collection<String> values) throws IOException {
Iterable<String> quoted =
Iterables.transform(
values,
new Function<String, String>() {
@Override public String apply(String arg) {
return "'" + arg.replace("'", "\\'") + "'";
}
});
out.append("[");
out.append(Joiner.on(", ").join(quoted));
out.append("]");
}
}
}
45 changes: 3 additions & 42 deletions src/com/google/javascript/jscomp/deps/DepsGenerator.java
Expand Up @@ -19,7 +19,6 @@
import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
Expand Down Expand Up @@ -395,52 +394,14 @@ protected String formatPathToDepsFile(String path) {
/**
* Writes goog.addDependency() lines for each DependencyInfo in depInfos.
*/
private void writeDepInfos(PrintStream out, Collection<DependencyInfo> depInfos) {
private void writeDepInfos(PrintStream out, Collection<DependencyInfo> depInfos)
throws IOException {
// Print dependencies.
// Lines look like this:
// goog.addDependency('../../path/to/file.js', ['goog.Delay'],
// ['goog.Disposable', 'goog.Timer']);
for (DependencyInfo depInfo : depInfos) {
Collection<String> provides = depInfo.getProvides();
Collection<String> requires = depInfo.getRequires();

out.print("goog.addDependency('" +
depInfo.getPathRelativeToClosureBase() + "', ");
writeJsArray(out, provides);
out.print(", ");
writeJsArray(out, requires);
Map<String, String> loadFlags = depInfo.getLoadFlags();
if (!loadFlags.isEmpty()) {
out.print(", ");
writeJsObject(out, loadFlags);
}
out.println(");");
}
}

private static void writeJsObject(PrintStream out, Map<String, String> map) {
List<String> entries = new ArrayList<>();
for (Map.Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey().replace("'", "\\'");
String value = entry.getValue().replace("'", "\\'");
entries.add("'" + key + "': '" + value + "'");
}
out.print("{");
out.print(Joiner.on(", ").join(entries));
out.print("}");
}

/**
* Prints a list of strings formatted as a JavaScript array of string
* literals.
*/
private static void writeJsArray(PrintStream out, Collection<String> values) {
if (values.isEmpty()) {
out.print("[]");
} else {
out.print("['");
out.print(Joiner.on("', '").join(values));
out.print("']");
DependencyInfo.Util.writeAddDependency(out, depInfo);
}
}

Expand Down
59 changes: 59 additions & 0 deletions test/com/google/javascript/jscomp/deps/DependencyInfoTest.java
@@ -0,0 +1,59 @@
/*
* Copyright 2016 The Closure Compiler Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.javascript.jscomp.deps;

import static com.google.common.truth.Truth.assertThat;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;

import junit.framework.TestCase;

import java.io.IOException;

/** Tests for {@link DependencyInfo}. */
public final class DependencyInfoTest extends TestCase {

public void testWriteAddDependency() throws IOException {
StringBuilder sb = new StringBuilder();
DependencyInfo.Util.writeAddDependency(
sb,
new SimpleDependencyInfo(
"../some/relative/path.js",
"/unused/absolute/path.js",
ImmutableList.of("provided.symbol", "other.provide"),
ImmutableList.of("required.symbol", "other.require"),
ImmutableMap.of("module", "goog", "lang", "es6")));
assertThat(sb.toString())
.isEqualTo(
"goog.addDependency('../some/relative/path.js', ['provided.symbol', 'other.provide'], "
+ "['required.symbol', 'other.require'], {'module': 'goog', 'lang': 'es6'});\n");
}

public void testWriteAddDependency_emptyArguments() throws IOException {
StringBuilder sb = new StringBuilder();
DependencyInfo.Util.writeAddDependency(
sb,
new SimpleDependencyInfo(
"path.js",
"unused.js",
ImmutableList.<String>of(),
ImmutableList.<String>of(),
ImmutableMap.<String, String>of()));
assertThat(sb.toString()).isEqualTo("goog.addDependency('path.js', [], []);\n");
}
}

0 comments on commit fc465c1

Please sign in to comment.