One-line fix to SelectionScript's fallback logic for
non-shardable subclasses.

Review at http://gwt-code-reviews.appspot.com/183801

Review by: robertvawter@google.com

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7771 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/core/ext/linker/impl/SelectionScriptLinker.java b/dev/core/src/com/google/gwt/core/ext/linker/impl/SelectionScriptLinker.java
index bd10d45..d78ee8d 100644
--- a/dev/core/src/com/google/gwt/core/ext/linker/impl/SelectionScriptLinker.java
+++ b/dev/core/src/com/google/gwt/core/ext/linker/impl/SelectionScriptLinker.java
@@ -125,7 +125,7 @@
   public ArtifactSet link(TreeLogger logger, LinkerContext context,
       ArtifactSet artifacts) throws UnableToCompleteException {
     ArtifactSet toReturn = link(logger, context, artifacts, true);
-    toReturn = link(logger, context, artifacts, false);
+    toReturn = link(logger, context, toReturn, false);
     return toReturn;
   }
 
diff --git a/user/test/com/google/gwt/core/ext/LinkerSuite.java b/user/test/com/google/gwt/core/ext/LinkerSuite.java
index 0728c04..4c47a70 100644
--- a/user/test/com/google/gwt/core/ext/LinkerSuite.java
+++ b/user/test/com/google/gwt/core/ext/LinkerSuite.java
@@ -16,6 +16,7 @@
 package com.google.gwt.core.ext;
 
 import com.google.gwt.core.ext.linker.impl.SelectionScriptJavaScriptTest;
+import com.google.gwt.core.ext.linker.impl.SelectionScriptLinkerUnitTest;
 import com.google.gwt.core.ext.test.IFrameLinkerTest;
 import com.google.gwt.core.ext.test.XSLinkerTest;
 import com.google.gwt.junit.tools.GWTTestSuite;
@@ -23,7 +24,8 @@
 import junit.framework.Test;
 
 /**
- * Runs the linker tests.  See the subclasses of {@link LinkerTest}.
+ * Runs the linker tests. See the subclasses of
+ * {@link com.google.gwt.core.ext.test.LinkerTest}.
  */
 public class LinkerSuite {
 
@@ -33,10 +35,11 @@
     // $JUnit-BEGIN$
     suite.addTestSuite(IFrameLinkerTest.class);
     suite.addTestSuite(SelectionScriptJavaScriptTest.class);
+    suite.addTestSuite(SelectionScriptLinkerUnitTest.class);
     suite.addTestSuite(XSLinkerTest.class);
     /*
-     *  Note: Single-script linking is disabled by default, because
-     *  it only works when the test is run for a single permutation.
+     * Note: Single-script linking is disabled by default, because it only works
+     * when the test is run for a single permutation.
      */
     // suite.addTestSuite(SingleScriptLinkerTest.class);
     // $JUnit-END$
diff --git a/user/test/com/google/gwt/core/ext/linker/impl/MockTemplate.js b/user/test/com/google/gwt/core/ext/linker/impl/MockTemplate.js
new file mode 100644
index 0000000..e16bb86
--- /dev/null
+++ b/user/test/com/google/gwt/core/ext/linker/impl/MockTemplate.js
@@ -0,0 +1 @@
+// This template file is used by SelectionScriptLinkerUnitTest
diff --git a/user/test/com/google/gwt/core/ext/linker/impl/SelectionScriptLinkerUnitTest.java b/user/test/com/google/gwt/core/ext/linker/impl/SelectionScriptLinkerUnitTest.java
new file mode 100644
index 0000000..6b84a5c
--- /dev/null
+++ b/user/test/com/google/gwt/core/ext/linker/impl/SelectionScriptLinkerUnitTest.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright 2010 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.core.ext.linker.impl;
+
+import com.google.gwt.core.ext.LinkerContext;
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.linker.Artifact;
+import com.google.gwt.core.ext.linker.ArtifactSet;
+import com.google.gwt.core.ext.linker.ConfigurationProperty;
+import com.google.gwt.core.ext.linker.SelectionProperty;
+import com.google.gwt.core.ext.linker.StatementRanges;
+import com.google.gwt.dev.Permutation;
+import com.google.gwt.dev.cfg.BindingProperty;
+import com.google.gwt.dev.cfg.StaticPropertyOracle;
+import com.google.gwt.dev.jjs.PermutationResult;
+
+import junit.framework.TestCase;
+
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+/**
+ * A regular JUnit test case for {@link SelectionScriptLinker}.
+ */
+public class SelectionScriptLinkerUnitTest extends TestCase {
+  private static class NonShardableSelectionScriptLinker extends
+      SelectionScriptLinker {
+    @Override
+    protected String getCompilationExtension(TreeLogger logger,
+        LinkerContext context) {
+      return ".js";
+    }
+
+    @Override
+    protected String getModulePrefix(TreeLogger logger, LinkerContext context,
+        String strongName) {
+      return "MODULE_PREFIX";
+    }
+
+    @Override
+    protected String getModuleSuffix(TreeLogger logger, LinkerContext context) {
+      return "MODULE_SUFFIX";
+    }
+
+    @Override
+    protected String getSelectionScriptTemplate(TreeLogger logger,
+        LinkerContext context) {
+      return SelectionScriptLinkerUnitTest.class.getPackage().getName().replace(
+          '.', '/')
+          + "/MockTemplate.js";
+    }
+
+    @Override
+    public String getDescription() {
+      return getClass().getName();
+    }
+  }
+
+  private static class MockLinkerContext implements LinkerContext {
+    @Override
+    public SortedSet<ConfigurationProperty> getConfigurationProperties() {
+      return new TreeSet<ConfigurationProperty>();
+    }
+
+    @Override
+    public String getModuleFunctionName() {
+      return "test";
+    }
+
+    @Override
+    public long getModuleLastModified() {
+      return 0;
+    }
+
+    @Override
+    public String getModuleName() {
+      return "test";
+    }
+
+    @Override
+    public SortedSet<SelectionProperty> getProperties() {
+      return new TreeSet<SelectionProperty>();
+    }
+
+    @Override
+    public boolean isOutputCompact() {
+      return true;
+    }
+
+    @Override
+    public String optimizeJavaScript(TreeLogger logger, String jsProgram) {
+      return jsProgram;
+    }
+  }
+
+  private static class MockPermutationResult implements PermutationResult {
+    private ArtifactSet artifacts = new ArtifactSet();
+
+    @Override
+    public void addArtifacts(Collection<? extends Artifact<?>> newArtifacts) {
+      artifacts.addAll(newArtifacts);
+    }
+
+    @Override
+    public ArtifactSet getArtifacts() {
+      return artifacts;
+    }
+
+    @Override
+    public byte[][] getJs() {
+      return new byte[][] {
+          getBytes("code for fragment 0"), getBytes("code for fragment 1")};
+    }
+
+    @Override
+    public Permutation getPermutation() {
+      return new Permutation(0, new StaticPropertyOracle(
+          new BindingProperty[0], new String[0],
+          new com.google.gwt.dev.cfg.ConfigurationProperty[0]));
+    }
+
+    @Override
+    public byte[] getSerializedSymbolMap() {
+      return getBytes("symbol map");
+    }
+
+    @Override
+    public StatementRanges[] getStatementRanges() {
+      ArrayList<StatementRanges> ranges = new ArrayList<StatementRanges>();
+      for (byte[] js : getJs()) {
+        ranges.add(new MockStatementRanges(js.length));
+      }
+      return ranges.toArray(new StatementRanges[0]);
+    }
+  }
+
+  private static class MockStatementRanges implements StatementRanges {
+    private int length;
+
+    MockStatementRanges(int length) {
+      this.length = length;
+    }
+
+    @Override
+    public int end(int i) {
+      return length;
+    }
+
+    @Override
+    public int numStatements() {
+      return 1;
+    }
+
+    @Override
+    public int start(int i) {
+      return 0;
+    }
+  }
+
+  private static byte[] getBytes(String string) {
+    try {
+      return string.getBytes("UTF-8");
+    } catch (UnsupportedEncodingException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  /**
+   * Test that running a non-shardable linker in simulated sharding mode does
+   * not lose the permutations.
+   */
+  public void testNonShardableHasPermutations()
+      throws UnableToCompleteException {
+    ArtifactSet artifacts = new ArtifactSet();
+
+    StandardCompilationResult result = new StandardCompilationResult(
+        new MockPermutationResult());
+    result.addSelectionPermutation(new TreeMap<SelectionProperty, String>());
+    artifacts.add(result);
+
+    ArtifactSet updated = new NonShardableSelectionScriptLinker().link(
+        TreeLogger.NULL, new MockLinkerContext(), artifacts);
+
+    SortedSet<SelectionInformation> selectionInfos = updated.find(SelectionInformation.class);
+    assertEquals(1, selectionInfos.size());
+  }
+}