Use same logic for -bindAddress in CodeServer and DevMode

Specifically wrt wildcard addresses, where DevMode used localhost's
host address while CodeServer used localhost's host name.

Bug: #8467, #8910
Bug-Link: https://github.com/gwtproject/gwt/issues/8467
Bug-Link: https://github.com/gwtproject/gwt/issues/8910
Change-Id: Ie265d9885aa0ec4a7ab26d32417a0c5539cfa80a
diff --git a/dev/codeserver/java/com/google/gwt/dev/codeserver/Options.java b/dev/codeserver/java/com/google/gwt/dev/codeserver/Options.java
index 0ba0f06..984c5bb 100644
--- a/dev/codeserver/java/com/google/gwt/dev/codeserver/Options.java
+++ b/dev/codeserver/java/com/google/gwt/dev/codeserver/Options.java
@@ -20,6 +20,7 @@
 import com.google.gwt.dev.ArgProcessorBase;
 import com.google.gwt.dev.cfg.ModuleDef;
 import com.google.gwt.dev.jjs.JsOutputOption;
+import com.google.gwt.dev.util.arg.ArgHandlerBindAddress;
 import com.google.gwt.dev.util.arg.ArgHandlerClosureFormattedOutput;
 import com.google.gwt.dev.util.arg.ArgHandlerGenerateJsInteropExports;
 import com.google.gwt.dev.util.arg.ArgHandlerIncrementalCompile;
@@ -28,6 +29,7 @@
 import com.google.gwt.dev.util.arg.ArgHandlerScriptStyle;
 import com.google.gwt.dev.util.arg.ArgHandlerSetProperties;
 import com.google.gwt.dev.util.arg.ArgHandlerSourceLevel;
+import com.google.gwt.dev.util.arg.OptionBindAddress;
 import com.google.gwt.dev.util.arg.OptionClosureFormattedOutput;
 import com.google.gwt.dev.util.arg.OptionGenerateJsInteropExports;
 import com.google.gwt.dev.util.arg.OptionIncrementalCompile;
@@ -46,11 +48,8 @@
 import com.google.gwt.util.tools.ArgHandlerExtra;
 import com.google.gwt.util.tools.ArgHandlerFlag;
 import com.google.gwt.util.tools.ArgHandlerInt;
-import com.google.gwt.util.tools.ArgHandlerString;
 
 import java.io.File;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.LinkedHashSet;
@@ -74,8 +73,8 @@
   private final List<String> moduleNames = new ArrayList<String>();
   private boolean allowMissingSourceDir = false;
   private final List<File> sourcePath = new ArrayList<File>();
-  private String bindAddress = "127.0.0.1";
-  private String preferredHost = "localhost";
+  private String bindAddress = ArgHandlerBindAddress.DEFAULT_BIND_ADDRESS;
+  private String preferredHost = ArgHandlerBindAddress.DEFAULT_BIND_ADDRESS;
   private int port = 9876;
 
   private RecompileListener recompileListener = RecompileListener.NONE;
@@ -325,7 +324,6 @@
 
     public ArgProcessor() {
       registerHandler(new AllowMissingSourceDirFlag());
-      registerHandler(new BindAddressFlag());
       registerHandler(new CompileTestFlag());
       registerHandler(new CompileTestRecompilesFlag());
       registerHandler(new FailOnErrorFlag());
@@ -335,6 +333,27 @@
       registerHandler(new SourceFlag());
       registerHandler(new WorkDirFlag());
       registerHandler(new LauncherDir());
+      registerHandler(new ArgHandlerBindAddress(new OptionBindAddress() {
+        @Override
+        public String getBindAddress() {
+          return Options.this.bindAddress;
+        }
+
+        @Override
+        public String getConnectAddress() {
+          return Options.this.preferredHost;
+        }
+
+        @Override
+        public void setBindAddress(String bindAddress) {
+          Options.this.bindAddress = bindAddress;
+        }
+
+        @Override
+        public void setConnectAddress(String connectAddress) {
+          Options.this.preferredHost = connectAddress;
+        }
+      }));
       registerHandler(new ArgHandlerScriptStyle(new OptionScriptStyle() {
         @Override
         public JsOutputOption getOutput() {
@@ -504,43 +523,6 @@
     }
   }
 
-  private class BindAddressFlag extends ArgHandlerString {
-
-    @Override
-    public String getTag() {
-      return "-bindAddress";
-    }
-
-    @Override
-    public String[] getTagArgs() {
-      return new String[] {"address"};
-    }
-
-    @Override
-    public String getPurpose() {
-      return "The ip address of the code server. Defaults to 127.0.0.1.";
-    }
-
-    @Override
-    public boolean setString(String newValue) {
-      try {
-        InetAddress newBindAddress = InetAddress.getByName(newValue);
-        if (newBindAddress.isAnyLocalAddress()) {
-          preferredHost = InetAddress.getLocalHost().getHostName();
-        } else {
-          preferredHost = newValue;
-        }
-      } catch (UnknownHostException e) {
-        System.err.println("Can't resolve bind address: " + newValue);
-        return false;
-      }
-
-      // Save the original since there's no way to get it back from an InetAddress.
-      bindAddress = newValue;
-      return true;
-    }
-  }
-
   private class PortFlag extends ArgHandlerInt {
 
     @Override
diff --git a/dev/core/src/com/google/gwt/dev/DevModeBase.java b/dev/core/src/com/google/gwt/dev/DevModeBase.java
index 47f8f22..3618977 100644
--- a/dev/core/src/com/google/gwt/dev/DevModeBase.java
+++ b/dev/core/src/com/google/gwt/dev/DevModeBase.java
@@ -34,9 +34,11 @@
 import com.google.gwt.dev.ui.DoneCallback;
 import com.google.gwt.dev.ui.DoneEvent;
 import com.google.gwt.dev.util.BrowserInfo;
+import com.google.gwt.dev.util.arg.ArgHandlerBindAddress;
 import com.google.gwt.dev.util.arg.ArgHandlerEnableGeneratorResultCaching;
 import com.google.gwt.dev.util.arg.ArgHandlerGenDir;
 import com.google.gwt.dev.util.arg.ArgHandlerLogLevel;
+import com.google.gwt.dev.util.arg.OptionBindAddress;
 import com.google.gwt.dev.util.log.speedtracer.DevModeEventType;
 import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
 import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
@@ -44,9 +46,7 @@
 import com.google.gwt.util.tools.ArgHandlerString;
 
 import java.io.File;
-import java.net.InetAddress;
 import java.net.URL;
-import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -110,62 +110,6 @@
   }
 
   /**
-   * Handles the -bindAddress command line flag.
-   */
-  protected static class ArgHandlerBindAddress extends ArgHandlerString {
-
-    private static final String BIND_ADDRESS_TAG = "-bindAddress";
-    private static final String DEFAULT_BIND_ADDRESS = "127.0.0.1";
-
-    private final OptionBindAddress options;
-
-    public ArgHandlerBindAddress(OptionBindAddress options) {
-      this.options = options;
-    }
-
-    @Override
-    public String[] getDefaultArgs() {
-      return new String[]{BIND_ADDRESS_TAG, DEFAULT_BIND_ADDRESS};
-    }
-
-    @Override
-    public String getPurpose() {
-      return "Specifies the bind address for the code server and web server " + "(defaults to "
-          + DEFAULT_BIND_ADDRESS + ")";
-    }
-
-    @Override
-    public String getTag() {
-      return BIND_ADDRESS_TAG;
-    }
-
-    @Override
-    public String[] getTagArgs() {
-      return new String[]{"host-name-or-address"};
-    }
-
-    @Override
-    public boolean setString(String value) {
-      try {
-        InetAddress address = InetAddress.getByName(value);
-        options.setBindAddress(value);
-        if (address.isAnyLocalAddress()) {
-          // replace a wildcard address with our machine's local address
-          // this isn't fully accurate, as there is no guarantee we will get
-          // the right one on a multihomed host
-          options.setConnectAddress(InetAddress.getLocalHost().getHostAddress());
-        } else {
-          options.setConnectAddress(value);
-        }
-        return true;
-      } catch (UnknownHostException e) {
-        System.err.println("-bindAddress host \"" + value + "\" unknown");
-        return false;
-      }
-    }
-  }
-
-  /**
    * Handles the -codeServerPort command line flag.
    */
   protected static class ArgHandlerCodeServerPort extends ArgHandlerString {
@@ -539,19 +483,6 @@
   }
 
   /**
-   * Controls what local address to bind to.
-   */
-  protected interface OptionBindAddress {
-    String getBindAddress();
-
-    String getConnectAddress();
-
-    void setBindAddress(String bindAddress);
-
-    void setConnectAddress(String connectAddress);
-  }
-
-  /**
    * Controls what port the code server listens on.
    */
   protected interface OptionCodeServerPort {
diff --git a/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerBindAddress.java b/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerBindAddress.java
new file mode 100644
index 0000000..5282b4f
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerBindAddress.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * 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.gwt.dev.util.arg;
+
+import com.google.gwt.util.tools.ArgHandlerString;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * Handles the -bindAddress command line flag.
+ */
+public class ArgHandlerBindAddress extends ArgHandlerString {
+
+  private static final String BIND_ADDRESS_TAG = "-bindAddress";
+  public static final String DEFAULT_BIND_ADDRESS = "127.0.0.1";
+
+  private final OptionBindAddress options;
+
+  public ArgHandlerBindAddress(OptionBindAddress options) {
+    this.options = options;
+  }
+
+  @Override
+  public String[] getDefaultArgs() {
+    return new String[]{BIND_ADDRESS_TAG, DEFAULT_BIND_ADDRESS};
+  }
+
+  @Override
+  public String getPurpose() {
+    return "Specifies the bind address for the code server and web server " + "(defaults to "
+        + DEFAULT_BIND_ADDRESS + ")";
+  }
+
+  @Override
+  public String getTag() {
+    return BIND_ADDRESS_TAG;
+  }
+
+  @Override
+  public String[] getTagArgs() {
+    return new String[]{"host-name-or-address"};
+  }
+
+  @Override
+  public boolean setString(String value) {
+    try {
+      InetAddress address = InetAddress.getByName(value);
+      options.setBindAddress(value);
+      if (address.isAnyLocalAddress()) {
+        // replace a wildcard address with our machine's local address
+        // this isn't fully accurate, as there is no guarantee we will get
+        // the right one on a multihomed host
+        options.setConnectAddress(InetAddress.getLocalHost().getHostAddress());
+      } else {
+        options.setConnectAddress(value);
+      }
+      return true;
+    } catch (UnknownHostException e) {
+      System.err.println("-bindAddress host \"" + value + "\" unknown");
+      return false;
+    }
+  }
+}
diff --git a/dev/core/src/com/google/gwt/dev/util/arg/OptionBindAddress.java b/dev/core/src/com/google/gwt/dev/util/arg/OptionBindAddress.java
new file mode 100644
index 0000000..66cf07e
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/util/arg/OptionBindAddress.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * 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.gwt.dev.util.arg;
+
+/**
+ * Controls what local address to bind to.
+ */
+public interface OptionBindAddress {
+
+  String getBindAddress();
+
+  String getConnectAddress();
+
+  void setBindAddress(String bindAddress);
+
+  void setConnectAddress(String connectAddress);
+}