Robbie V implemented a fix so that Stage.TOOL doesn't return an Injector whose methods won't work properly.

git-svn-id: https://google-guice.googlecode.com/svn/trunk@590 d779f126-a31b-0410-b53b-1d3aecad763e
diff --git a/src/com/google/inject/InjectorBuilder.java b/src/com/google/inject/InjectorBuilder.java
index 5c1086d..5ee377d 100644
--- a/src/com/google/inject/InjectorBuilder.java
+++ b/src/com/google/inject/InjectorBuilder.java
@@ -30,6 +30,7 @@
 import com.google.inject.spi.InjectionPoint;
 import java.lang.reflect.Member;
 import java.util.List;
+import java.util.Map;
 import java.util.logging.Logger;
 
 /**
@@ -101,8 +102,7 @@
     // If we're in the tool stage, stop here. Don't eagerly inject or load
     // anything.
     if (stage == Stage.TOOL) {
-      // TODO: Wrap this and prevent usage of anything besides getBindings().
-      return injector;
+      return new ToolStageInjector(injector);
     }
 
     fulfillInjectionRequests();
@@ -278,4 +278,44 @@
     }
   }
 
+  /** {@link Injector} exposed to users in {@link Stage#TOOL}. */
+  static class ToolStageInjector implements Injector {
+    private final Injector delegateInjector;
+    
+    ToolStageInjector(Injector delegateInjector) {
+      this.delegateInjector = delegateInjector;
+    }
+    public void injectMembers(Object o) {
+      throw new UnsupportedOperationException(
+        "Injector.injectMembers(Object) is not supported in Stage.TOOL");
+    }
+    public Map<Key<?>, Binding<?>> getBindings() {
+      return this.delegateInjector.getBindings();
+    }
+    public <T> Binding<T> getBinding(Key<T> key) {
+      return this.delegateInjector.getBinding(key);
+    }
+    public <T> Binding<T> getBinding(Class<T> type) {
+      return this.delegateInjector.getBinding(type);
+    }
+    public <T> List<Binding<T>> findBindingsByType(TypeLiteral<T> type) {
+      return this.delegateInjector.findBindingsByType(type);
+    }
+    public <T> Provider<T> getProvider(Key<T> key) {
+      throw new UnsupportedOperationException(
+        "Injector.getProvider(Key<T>) is not supported in Stage.TOOL");
+    }
+    public <T> Provider<T> getProvider(Class<T> type) {
+      throw new UnsupportedOperationException(
+        "Injector.getProvider(Class<T>) is not supported in Stage.TOOL");
+    }
+    public <T> T getInstance(Key<T> key) {
+      throw new UnsupportedOperationException(
+        "Injector.getInstance(Key<T>) is not supported in Stage.TOOL");
+    }
+    public <T> T getInstance(Class<T> type) {
+      throw new UnsupportedOperationException(
+        "Injector.getInstance(Class<T>) is not supported in Stage.TOOL");
+    }
+  }
 }
diff --git a/src/com/google/inject/Stage.java b/src/com/google/inject/Stage.java
index e13acb3..babb371 100644
--- a/src/com/google/inject/Stage.java
+++ b/src/com/google/inject/Stage.java
@@ -27,7 +27,8 @@
    * We're running in a tool (an IDE plugin for example). We need binding
    * meta data but not a functioning Injector. Do not inject members of
    * instances. Do not load eager singletons. Do as little as possible so
-   * our tools run nice and snappy.
+   * our tools run nice and snappy. Injectors created in this stage cannot
+   * be used to satisfy injections.
    */
   TOOL,
 
diff --git a/test/com/google/inject/InjectorTest.java b/test/com/google/inject/InjectorTest.java
index 8edba4a..d8e5a1f 100644
--- a/test/com/google/inject/InjectorTest.java
+++ b/test/com/google/inject/InjectorTest.java
@@ -17,11 +17,10 @@
 package com.google.inject;
 
 import static com.google.inject.Asserts.assertNotSerializable;
-import junit.framework.TestCase;
-
 import java.io.IOException;
 import java.lang.annotation.Retention;
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import junit.framework.TestCase;
 
 /**
  * @author crazybob@google.com (Bob Lee)
@@ -284,7 +283,40 @@
     });
   }
 
+  public void testToolStageInjectorRestrictions() {
+    Injector injector = Guice.createInjector(Stage.TOOL);
+    try {
+      injector.injectMembers(new Object());
+      fail("Non-SPI Injector methods must throw an exception in the TOOL stage.");
+    } catch (UnsupportedOperationException expected) {
+    }
+
+    try {
+      injector.getInstance(Injector.class);
+      fail("Non-SPI Injector methods must throw an exception in the TOOL stage.");
+    } catch (UnsupportedOperationException expected) {
+    }
+
+    try {
+      injector.getInstance(Key.get(Injector.class));
+      fail("Non-SPI Injector methods must throw an exception in the TOOL stage.");
+    } catch (UnsupportedOperationException expected) {
+    }
+
+    try {
+      injector.getProvider(Injector.class);
+      fail("Non-SPI Injector methods must throw an exception in the TOOL stage.");
+    } catch (UnsupportedOperationException expected) {
+    }
+
+    try {
+      injector.getProvider(Key.get(Injector.class));
+      fail("Non-SPI Injector methods must throw an exception in the TOOL stage.");
+    } catch (UnsupportedOperationException expected) {
+    }
+  }
+
   static class MyRunnable implements Runnable {
    public void run() {}
   }  
-}
\ No newline at end of file
+}