Make sure "goog.global" is $wnd if not defined.

Change-Id: I1de7bab12a2d13905194a0f454e3b82bfe971c3a
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
index 8a8b69f..1eebb9d 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
@@ -530,6 +530,9 @@
     private final JsName arrayLength = objectScope.declareUnobfuscatableName("length");
     private final JsName globalTemp = topScope.declareUnobfuscatableName("_");
     private final JsName prototype = objectScope.declareUnobfuscatableName("prototype");
+    private final JsName wnd = topScope.declareUnobfuscatableName("$wnd");
+    private final JsName goog = topScope.declareUnobfuscatableName("goog");
+    private final JsName global = topScope.declareUnobfuscatableName("global");
 
     @Override
     public JsExpression transformArrayLength(JArrayLength expression) {
@@ -1238,14 +1241,18 @@
     }
 
     private Set<JDeclaredType> generatePreamble(JProgram program) {
+      SourceInfo programSourceInfo = jsProgram.getSourceInfo();
+
       // Reserve the "_" identifier.
-      JsVars vars = new JsVars(jsProgram.getSourceInfo());
-      vars.add(new JsVar(jsProgram.getSourceInfo(), globalTemp));
+      JsVars vars = new JsVars(programSourceInfo, new JsVar(programSourceInfo, globalTemp));
       addVarsIfNotEmpty(vars);
 
       // Generate immortal types in the preamble.
       generateImmortalTypes(vars);
 
+      // Generate the assignment to goog.global.
+      generateGoogGlobalInitialization(programSourceInfo);
+
       //  Perform necessary polyfills.
       addTypeDefinitionStatement(
           program.getIndexedType(RuntimeConstants.RUNTIME),
@@ -1273,6 +1280,26 @@
       return preambleTypes;
     }
 
+    private void generateGoogGlobalInitialization(SourceInfo programSourceInfo) {
+      // $wnd.goog = $wnd.goog || {}
+      JsNameRef wndGoog  = goog.makeQualifiedRef(programSourceInfo, wnd.makeRef(programSourceInfo));
+      generatePropertyInitialization(
+          programSourceInfo, wndGoog, JsObjectLiteral.builder(programSourceInfo).build());
+
+      // $wnd.goog.global = $wnd.goog.global || $wnd
+      JsNameRef wndGoogGlobal  = global.makeQualifiedRef(programSourceInfo, wndGoog);
+      generatePropertyInitialization(
+          programSourceInfo, wndGoogGlobal, wnd.makeRef(programSourceInfo));
+    }
+
+    private void generatePropertyInitialization(
+        SourceInfo sourceInfo, JsNameRef qualifiedNameRef, JsExpression initializer) {
+      getGlobalStatements().add(
+          new JsBinaryOperation(sourceInfo, JsBinaryOperator.ASG, qualifiedNameRef,
+              new JsBinaryOperation(sourceInfo, JsBinaryOperator.OR,
+                  qualifiedNameRef, initializer)).makeStmt());
+    }
+
     private JsNameRef transformIntoLabelReference(SourceInfo info, JLabel label) {
       if (label == null) {
         return null;
diff --git a/user/test/com/google/gwt/core/interop/NativeJsTypeTest.java b/user/test/com/google/gwt/core/interop/NativeJsTypeTest.java
index b36456e..54527b3 100644
--- a/user/test/com/google/gwt/core/interop/NativeJsTypeTest.java
+++ b/user/test/com/google/gwt/core/interop/NativeJsTypeTest.java
@@ -466,6 +466,15 @@
     assertSame(MainWindow.window, AlsoMainWindow.window);
   }
 
+  @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "goog.global")
+  private static class WindowThroughGoogGlobal {
+    public static Object window;
+  }
+
+  public void testGoogGlobalAlias() {
+    assertSame(MainWindow.window, WindowThroughGoogGlobal.window);
+  }
+
   @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Error")
   private static class NativeError {
     public String message;