langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java
changeset 41938 8e66bf10fcec
parent 41637 7b24b4c32ee6
child 41992 720257f5307d
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java	Thu Nov 03 09:12:02 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java	Thu Nov 03 13:59:15 2016 -0700
@@ -43,6 +43,7 @@
 import java.util.ServiceLoader;
 import java.util.Set;
 import java.util.TreeSet;
+import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 import java.util.stream.StreamSupport;
 
@@ -556,18 +557,44 @@
     ADD_EXPORTS("--add-exports", "opt.arg.addExports", "opt.addExports", EXTENDED, BASIC) {
         @Override
         public boolean process(OptionHelper helper, String option, String arg) {
-            String prev = helper.get(ADD_EXPORTS);
-            helper.put(ADD_EXPORTS.primaryName, (prev == null) ? arg : prev + '\0' + arg);
-            return false;
+            if (arg.isEmpty()) {
+                helper.error("err.no.value.for.option", option);
+                return true;
+            } else if (getPattern().matcher(arg).matches()) {
+                String prev = helper.get(ADD_EXPORTS);
+                helper.put(ADD_EXPORTS.primaryName, (prev == null) ? arg : prev + '\0' + arg);
+                return false;
+            } else {
+                helper.error("err.bad.value.for.option", option, arg);
+                return true;
+            }
+        }
+
+        @Override
+        public Pattern getPattern() {
+            return Pattern.compile("([^/]+)/([^=]+)=(,*[^,].*)");
         }
     },
 
     ADD_READS("--add-reads", "opt.arg.addReads", "opt.addReads", EXTENDED, BASIC) {
         @Override
         public boolean process(OptionHelper helper, String option, String arg) {
-            String prev = helper.get(ADD_READS);
-            helper.put(ADD_READS.primaryName, (prev == null) ? arg : prev + '\0' + arg);
-            return false;
+            if (arg.isEmpty()) {
+                helper.error("err.no.value.for.option", option);
+                return true;
+            } else if (getPattern().matcher(arg).matches()) {
+                String prev = helper.get(ADD_READS);
+                helper.put(ADD_READS.primaryName, (prev == null) ? arg : prev + '\0' + arg);
+                return false;
+            } else {
+                helper.error("err.bad.value.for.option", option, arg);
+                return true;
+            }
+        }
+
+        @Override
+        public Pattern getPattern() {
+            return Pattern.compile("([^=]+)=(,*[^,].*)");
         }
     },
 
@@ -577,6 +604,7 @@
             String prev = helper.get(XMODULE);
             if (prev != null) {
                 helper.error("err.option.too.many", XMODULE.primaryName);
+                return true;
             }
             helper.put(XMODULE.primaryName, arg);
             return false;
@@ -585,9 +613,50 @@
 
     MODULE("--module -m", "opt.arg.m", "opt.m", STANDARD, BASIC),
 
-    ADD_MODULES("--add-modules", "opt.arg.addmods", "opt.addmods", STANDARD, BASIC),
+    ADD_MODULES("--add-modules", "opt.arg.addmods", "opt.addmods", STANDARD, BASIC) {
+        @Override
+        public boolean process(OptionHelper helper, String option, String arg) {
+            if (arg.isEmpty()) {
+                helper.error("err.no.value.for.option", option);
+                return true;
+            } else if (getPattern().matcher(arg).matches()) {
+                String prev = helper.get(ADD_MODULES);
+                // since the individual values are simple names, we can simply join the
+                // values of multiple --add-modules options with ','
+                helper.put(ADD_MODULES.primaryName, (prev == null) ? arg : prev + ',' + arg);
+                return false;
+            } else {
+                helper.error("err.bad.value.for.option", option, arg);
+                return true;
+            }
+        }
 
-    LIMIT_MODULES("--limit-modules", "opt.arg.limitmods", "opt.limitmods", STANDARD, BASIC),
+        @Override
+        public Pattern getPattern() {
+            return Pattern.compile(",*[^,].*");
+        }
+    },
+
+    LIMIT_MODULES("--limit-modules", "opt.arg.limitmods", "opt.limitmods", STANDARD, BASIC) {
+        @Override
+        public boolean process(OptionHelper helper, String option, String arg) {
+            if (arg.isEmpty()) {
+                helper.error("err.no.value.for.option", option);
+                return true;
+            } else if (getPattern().matcher(arg).matches()) {
+                helper.put(LIMIT_MODULES.primaryName, arg); // last one wins
+                return false;
+            } else {
+                helper.error("err.bad.value.for.option", option, arg);
+                return true;
+            }
+        }
+
+        @Override
+        public Pattern getPattern() {
+            return Pattern.compile(",*[^,].*");
+        }
+    },
 
     // This option exists only for the purpose of documenting itself.
     // It's actually implemented by the CommandLine class.
@@ -963,20 +1032,24 @@
      */
     public boolean handleOption(OptionHelper helper, String arg, Iterator<String> rest) {
         if (hasArg()) {
+            String option;
             String operand;
             int sep = findSeparator(arg);
             if (getArgKind() == Option.ArgKind.ADJACENT) {
+                option = primaryName; // aliases not supported
                 operand = arg.substring(primaryName.length());
             } else if (sep > 0) {
+                option = arg.substring(0, sep);
                 operand = arg.substring(sep + 1);
             } else {
                 if (!rest.hasNext()) {
                     helper.error("err.req.arg", arg);
                     return false;
                 }
+                option = arg;
                 operand = rest.next();
             }
-            return !process(helper, arg, operand);
+            return !process(helper, option, operand);
         } else {
             return !process(helper, arg);
         }
@@ -1033,6 +1106,15 @@
     }
 
     /**
+     * Returns a pattern to analyze the value for an option.
+     * @return the pattern
+     * @throws UnsupportedOperationException if an option does not provide a pattern.
+     */
+    public Pattern getPattern() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
      * Scans a word to find the first separator character, either colon or equals.
      * @param word the word to be scanned
      * @return the position of the first':' or '=' character in the word,