Repository: google/closure-compiler
Pull request #1310 (2015-12-18 21:03:11)

Allow more characters to be used in output module names
This has been asked for by others, but now I need it.

In theory, an output module name could be any valid file path. This PR just loosens the existing requirements slightly to allow "." and "-" as valid characters.


Patch:
diff --git a/src/com/google/javascript/jscomp/CommandLineRunner.java b/src/com/google/javascript/jscomp/CommandLineRunner.java
index b225ccb40..7d1e6ce93 100644
--- a/src/com/google/javascript/jscomp/CommandLineRunner.java
+++ b/src/com/google/javascript/jscomp/CommandLineRunner.java
@@ -27,6 +27,7 @@ import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.io.Files;
 import com.google.javascript.jscomp.SourceMap.LocationMapping;
+import com.google.javascript.rhino.TokenStream;
 import com.google.protobuf.TextFormat;
 
 import org.kohsuke.args4j.Argument;
@@ -117,6 +118,9 @@ public class CommandLineRunner extends
   // UTF-8 BOM is 0xEF, 0xBB, 0xBF, of which character code is 65279.
   public static final int UTF8_BOM_CODE = 65279;
 
+  // Allowable module name characters that aren't valid in a JS identifier
+  private static final Pattern extraModuleNameChars = Pattern.compile("[-.]+");
+
   private static class GuardLevel {
     final String name;
     final CheckLevel level;
@@ -1161,6 +1165,15 @@ public class CommandLineRunner extends
     options.addWarningsGuard(WhitelistWarningsGuard.fromFile(whitelistFile));
   }
 
+  @Override
+  protected void checkModuleName(String name)
+      throws FlagUsageException {
+    if (!TokenStream.isJSIdentifier(
+        extraModuleNameChars.matcher(name).replaceAll("_"))) {
+      throw new FlagUsageException("Invalid module name: '" + name + "'");
+    }
+  }
+
   @Override
   protected CompilerOptions createOptions() {
     CompilerOptions options = new CompilerOptions();


Test patch:
diff --git a/test/com/google/javascript/jscomp/CommandLineRunnerTest.java b/test/com/google/javascript/jscomp/CommandLineRunnerTest.java
index 684b31eed..4ca708df0 100644
--- a/test/com/google/javascript/jscomp/CommandLineRunnerTest.java
+++ b/test/com/google/javascript/jscomp/CommandLineRunnerTest.java
@@ -1579,6 +1579,33 @@ public final class CommandLineRunnerTest extends TestCase {
         + "\\n\\\"names\\\":[\\\"alert\\\"]\\n}\\n\"}]");
   }
 
+  public void testOutputModuleNaming() throws FlagUsageException {
+    String inputString = "[{\"src\": \"alert('foo');\", \"path\":\"foo.js\"}]";
+    args.add("--json_streams=BOTH");
+    args.add("--module=foo--bar.baz:1");
+
+    CommandLineRunner runner = new CommandLineRunner(
+        args.toArray(new String[]{}),
+        new ByteArrayInputStream(inputString.getBytes()),
+        new PrintStream(outReader),
+        new PrintStream(errReader));
+
+    lastCompiler = runner.getCompiler();
+    try {
+      runner.doRun();
+    } catch (IOException e) {
+      e.printStackTrace();
+      fail("Unexpected exception " + e);
+    }
+    String output = new String(outReader.toByteArray(), UTF_8);
+    assertThat(output).isEqualTo("[{\"src\":\"alert(\\\"foo\\\");\\n\","
+        + "\"path\":\"./foo--bar.baz.js\",\"source_map\":\"{\\n\\\"version\\\":3,"
+        + "\\n\\\"file\\\":\\\"./foo--bar.baz.js\\\",\\n\\\"lineCount\\\":1,"
+        + "\\n\\\"mappings\\\":\\\"AAAAA,KAAA,CAAM,KAAN;\\\","
+        + "\\n\\\"sources\\\":[\\\"foo.js\\\"],"
+        + "\\n\\\"names\\\":[\\\"alert\\\"]\\n}\\n\"}]");
+  }
+
   /* Helper functions */
 
   private void testSame(String original) {