Issue 32: forbid binding to guice framework types (Module, Binding, etc.)

git-svn-id: https://google-guice.googlecode.com/svn/trunk@246 d779f126-a31b-0410-b53b-1d3aecad763e
diff --git a/src/com/google/inject/BinderImpl.java b/src/com/google/inject/BinderImpl.java
index cb5e331..b34ab5a 100644
--- a/src/com/google/inject/BinderImpl.java
+++ b/src/com/google/inject/BinderImpl.java
@@ -31,9 +31,12 @@
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import org.aopalliance.intercept.MethodInterceptor;
@@ -453,14 +456,36 @@
     }
   }
 
+  private static Set<Class<?>> FORBIDDEN_TYPES = forbiddenTypes();
+
+  private static Set<Class<?>> forbiddenTypes() {
+    Set<Class<?>> set = new HashSet<Class<?>>();
+    Collections.addAll(set,
+
+        // It's unfortunate that we have to maintain a blacklist of specific
+        // classes, but we can't easily block the whole package because of
+        // all our unit tests.
+
+        AbstractModule.class,
+        Binder.class,
+        Binding.class,
+        Key.class,
+        Module.class,
+        Provider.class,
+        Scope.class,
+        TypeLiteral.class);
+    return Collections.unmodifiableSet(set);
+  }
+
   void putBinding(BindingImpl<?> binding) {
     Key<?> key = binding.getKey();
     Map<Key<?>, BindingImpl<?>> bindings = injector.internalBindings();
     Binding<?> original = bindings.get(key);
 
-    // Binding to Provider<?> is not allowed.
-    if (key.getRawType().equals(Provider.class)) {
-      addError(binding.getSource(), ErrorMessages.CANNOT_BIND_TO_PROVIDER);
+    Class<?> rawType = key.getRawType();
+    if (FORBIDDEN_TYPES.contains(rawType)) {
+      addError(binding.getSource(), ErrorMessages.CANNOT_BIND_TO_GUICE_TYPE,
+          rawType.getSimpleName());
       return;
     }
 
diff --git a/src/com/google/inject/ErrorMessages.java b/src/com/google/inject/ErrorMessages.java
index f852cb3..856670c 100644
--- a/src/com/google/inject/ErrorMessages.java
+++ b/src/com/google/inject/ErrorMessages.java
@@ -80,8 +80,8 @@
   static final String CONSTANT_CONVERSION_ERROR = "Error converting String"
       + " constant bound at %s to %s: %s";
 
-  static final String CANNOT_BIND_TO_PROVIDER = "Binding to Provider<?> is not"
-      + " allowed.";
+  static final String CANNOT_BIND_TO_GUICE_TYPE = "Binding to core guice" 
+      + " framework type is not allowed: %s.";
 
   static final String SCOPE_NOT_FOUND = "No scope is bound to %s.";
 
diff --git a/test/com/google/inject/ErrorHandlingTest.java b/test/com/google/inject/ErrorHandlingTest.java
index cbc3d40..ac5b30b 100644
--- a/test/com/google/inject/ErrorHandlingTest.java
+++ b/test/com/google/inject/ErrorHandlingTest.java
@@ -101,6 +101,8 @@
       } catch (Exception e) {
         addError(e);
       }
+
+      bind(Module.class).toInstance(this);
     }
   }
 }