Merges -r7431 from trunk to releases/2.0:

svn merge --ignore-ancestry -c 7431  https://google-web-toolkit.googlecode.com/svn/trunk .    
Ensures that instance methods of Array are downloaded initially.



git-svn-id: https://google-web-toolkit.googlecode.com/svn/releases/2.0@7504 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/CodeSplitter.java b/dev/core/src/com/google/gwt/dev/jjs/impl/CodeSplitter.java
index 0c0d090..28e20ee 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/CodeSplitter.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/CodeSplitter.java
@@ -453,6 +453,7 @@
     ControlFlowAnalyzer cfa = new ControlFlowAnalyzer(jprogram);
     cfa.setDependencyRecorder(dependencyRecorder);
     traverseEntry(jprogram, cfa, 0);
+    traverseClassArray(jprogram, cfa);
 
     dependencyRecorder.endDependencyGraph();
     return cfa;
@@ -566,6 +567,28 @@
   }
 
   /**
+   * Any instance method in the magic Array class must be in the initial
+   * download. The methods of that class are copied to a separate object the
+   * first time class Array is touched, and any methods added later won't be
+   * part of the copy.
+   */
+  private static void traverseClassArray(JProgram jprogram,
+      ControlFlowAnalyzer cfa) {
+    JDeclaredType typeArray = jprogram.getFromTypeMap("com.google.gwt.lang.Array");
+    if (typeArray == null) {
+      // It was pruned; nothing to do
+      return;
+    }
+
+    cfa.traverseFromInstantiationOf(typeArray);
+    for (JMethod method : typeArray.getMethods()) {
+      if (!method.isStatic()) {
+        cfa.traverseFrom(method);
+      }
+    }
+  }
+
+  /**
    * Traverse all code in the program that is reachable via split point
    * <code>splitPoint</code>.
    */
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java b/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java
index f62bba9..da64d91 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java
@@ -783,6 +783,14 @@
     rescuer.rescue(method);
   }
 
+  /**
+   * Assume <code>type</code> is instantiated, and find out what else will
+   * execute as a result.
+   */
+  public void traverseFromInstantiationOf(JDeclaredType type) {
+    rescuer.rescue(type, true, true);
+  }
+
   public void traverseFromLeftoversFragmentHasLoaded() {
     if (program.entryMethods.size() > 1) {
       traverseFrom(program.getIndexedMethod("AsyncFragmentLoader.browserLoaderLeftoversFragmentHasLoaded"));
diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/CodeSplitterTest.java b/dev/core/test/com/google/gwt/dev/jjs/impl/CodeSplitterTest.java
new file mode 100644
index 0000000..02ce1e7
--- /dev/null
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/CodeSplitterTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2008 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.jjs.impl;
+
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.dev.javac.impl.MockJavaResource;
+import com.google.gwt.dev.jjs.ast.JProgram;
+
+/**
+ * Tests class {@link CodeSplitter}.
+ */
+public class CodeSplitterTest extends OptimizerTestBase {
+  /**
+   * Tests that everything in the magic Array class is considered initially
+   * live.
+   */
+  public void testArrayIsInitial() throws UnableToCompleteException {
+    sourceOracle.addOrReplace(new MockJavaResource("com.google.gwt.lang.Array") {
+      @Override
+      protected CharSequence getContent() {
+        StringBuffer code = new StringBuffer();
+        code.append("package com.google.gwt.lang;\n");
+        code.append("public class Array {\n");
+        code.append("  private Class type;\n");
+        code.append("  public Class getClass() { return type; }\n");
+        code.append("}\n");
+        return code;
+      }
+    });
+
+    JProgram program = compileSnippet("void", "");
+    ControlFlowAnalyzer cfa = CodeSplitter.computeInitiallyLive(program);
+
+    assertTrue(cfa.getInstantiatedTypes().contains(
+        findType(program, "com.google.gwt.lang.Array")));
+    assertTrue(cfa.getLiveFieldsAndMethods().contains(
+        findMethod(findType(program, "com.google.gwt.lang.Array"), "getClass")));
+  }
+}
diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/OptimizerTestBase.java b/dev/core/test/com/google/gwt/dev/jjs/impl/OptimizerTestBase.java
index d7e7a59..fb5eef2 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/impl/OptimizerTestBase.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/OptimizerTestBase.java
@@ -65,21 +65,28 @@
   }
 
   public static JMethod findMainMethod(JProgram program) {
-    JDeclaredType mainType = program.getFromTypeMap("test.EntryPoint");
-    JMethod mainMethod = null;
-    for (JMethod method : mainType.getMethods()) {
-      if (method.getName().equals("onModuleLoad")) {
-        mainMethod = method;
-        break;
+    return findMethod(program, "onModuleLoad");
+  }
+
+  public static JMethod findMethod(JDeclaredType type, String methodName) {
+    for (JMethod method : type.getMethods()) {
+      if (method.getName().equals(methodName)) {
+        return method;
       }
     }
-    return mainMethod;
+
+    return null;
+  }
+
+  public static JMethod findMethod(JProgram program, String methodName) {
+    JDeclaredType mainType = program.getFromTypeMap("test.EntryPoint");
+    return findMethod(mainType, methodName);
   }
 
   /**
    * Finds a type by name. The type name may be short, e.g. <code>"Foo"</code>,
-   * or fully-qualified, e.g. <code>"com.google.example.Foo"</code>. If a
-   * short name is used, it must be unambiguous.
+   * or fully-qualified, e.g. <code>"com.google.example.Foo"</code>. If a short
+   * name is used, it must be unambiguous.
    */
   public static JDeclaredType findType(JProgram program, String typeName) {
     JDeclaredType type = program.getFromTypeMap(typeName);