Author: limpbizkit
Date: Sun Jun 21 11:13:01 2009
New Revision: 1025

Modified:
    trunk/src/com/google/inject/binder/LinkedBindingBuilder.java
    trunk/src/com/google/inject/internal/BindingBuilder.java
    trunk/src/com/google/inject/internal/ConstructorBindingImpl.java
    trunk/src/com/google/inject/spi/InjectionPoint.java
    trunk/test/com/google/inject/BindingTest.java
    trunk/test/com/google/inject/spi/ElementsTest.java

Log:
New API: toConstructor(Constructor, TypeLiteral).

The pair {Constructor, TypeLiteral} is necessary to specify a parameterized  
constructor reference (like "new HashMap<Integer, String>()")


Modified: trunk/src/com/google/inject/binder/LinkedBindingBuilder.java
==============================================================================
--- trunk/src/com/google/inject/binder/LinkedBindingBuilder.java        
(original)
+++ trunk/src/com/google/inject/binder/LinkedBindingBuilder.java        Sun Jun 
21  
11:13:01 2009
@@ -78,5 +78,11 @@
    /**
     * See the EDSL examples at {...@link com.google.inject.Binder}.
     */
-  ScopedBindingBuilder toConstructor(Constructor<? extends T> constructor);
+  <S extends T> ScopedBindingBuilder toConstructor(Constructor<S>  
constructor);
+
+  /**
+   * See the EDSL examples at {...@link com.google.inject.Binder}.
+   */
+  <S extends T> ScopedBindingBuilder toConstructor(
+      Constructor<S> constructor, TypeLiteral<? extends S> type);
  }

Modified: trunk/src/com/google/inject/internal/BindingBuilder.java
==============================================================================
--- trunk/src/com/google/inject/internal/BindingBuilder.java    (original)
+++ trunk/src/com/google/inject/internal/BindingBuilder.java    Sun Jun 21  
11:13:01 2009
@@ -130,19 +130,21 @@
      return this;
    }

-  public ScopedBindingBuilder toConstructor(Constructor<? extends T>  
constructor) {
+  public <S extends T> ScopedBindingBuilder toConstructor(Constructor<S>  
constructor) {
+    return toConstructor(constructor,  
TypeLiteral.get(constructor.getDeclaringClass()));
+  }
+
+  public <S extends T> ScopedBindingBuilder toConstructor(Constructor<S>  
constructor,
+      TypeLiteral<? extends S> type) {
      checkNotNull(constructor, "constructor");
+    checkNotNull(type, "type");
      checkNotTargetted();

      BindingImpl<T> base = getBinding();
-    TypeLiteral<T> keyType = base.getKey().getTypeLiteral();
-    TypeLiteral<? extends T> toConstruct =  
(constructor.getDeclaringClass() == keyType.getRawType())
-        ? keyType
-        : TypeLiteral.get(constructor.getDeclaringClass());

      Set<InjectionPoint> injectionPoints;
      try {
-      injectionPoints =  
InjectionPoint.forInstanceMethodsAndFields(toConstruct);
+      injectionPoints = InjectionPoint.forInstanceMethodsAndFields(type);
      } catch (ConfigurationException e) {
        copyErrorsToBinder(e);
        injectionPoints = e.getPartialValue();
@@ -150,8 +152,7 @@

      try {
        @SuppressWarnings("unchecked") // safe; constructor is a subtype of  
toConstruct
-      InjectionPoint constructorPoint =  
InjectionPoint.forConstructor((Constructor) constructor,
-          toConstruct);
+      InjectionPoint constructorPoint =  
InjectionPoint.forConstructor(constructor, type);
        setBinding(new ConstructorBindingImpl<T>(base.getKey(),  
base.getSource(), base.getScoping(),
            constructorPoint, injectionPoints));
      } catch (ConfigurationException e) {

Modified: trunk/src/com/google/inject/internal/ConstructorBindingImpl.java
==============================================================================
--- trunk/src/com/google/inject/internal/ConstructorBindingImpl.java     
(original)
+++ trunk/src/com/google/inject/internal/ConstructorBindingImpl.java    Sun  
Jun 21 11:13:01 2009
@@ -19,16 +19,17 @@
  import com.google.inject.Binder;
  import com.google.inject.ConfigurationException;
  import com.google.inject.Key;
-import static com.google.inject.internal.Preconditions.checkState;
+import com.google.inject.TypeLiteral;
  import static com.google.inject.internal.Annotations.findScopeAnnotation;
+import static com.google.inject.internal.Preconditions.checkState;
  import com.google.inject.spi.BindingTargetVisitor;
  import com.google.inject.spi.ConstructorBinding;
  import com.google.inject.spi.Dependency;
  import com.google.inject.spi.InjectionPoint;
+import java.lang.annotation.Annotation;
  import java.lang.reflect.Constructor;
  import java.lang.reflect.Method;
  import java.lang.reflect.Modifier;
-import java.lang.annotation.Annotation;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
@@ -153,8 +154,9 @@
    }

    public void applyTo(Binder binder) {
-    getScoping().applyTo(binder.withSource(getSource())
-        .bind(getKey()).toConstructor((Constructor)  
getConstructor().getMember()));
+    InjectionPoint constructor = getConstructor();
+     
getScoping().applyTo(binder.withSource(getSource()).bind(getKey()).toConstructor(
+        (Constructor) getConstructor().getMember(), (TypeLiteral)  
constructor.getDeclaringType()));
    }

    @Override public String toString() {

Modified: trunk/src/com/google/inject/spi/InjectionPoint.java
==============================================================================
--- trunk/src/com/google/inject/spi/InjectionPoint.java (original)
+++ trunk/src/com/google/inject/spi/InjectionPoint.java Sun Jun 21 11:13:01  
2009
@@ -88,6 +88,8 @@
      Key<?> key = null;
      try {
        key = Annotations.getKey(declaringType.getFieldType(field), field,  
annotations, errors);
+    } catch (ConfigurationException e) {
+      errors.merge(e.getErrorMessages());
      } catch (ErrorsException e) {
        errors.merge(e.getErrors());
      }
@@ -111,6 +113,8 @@
          Key<?> key = Annotations.getKey(parameterType, member,  
parameterAnnotations, errors);
          dependencies.add(newDependency(key,  
Nullability.allowsNull(parameterAnnotations), index));
          index++;
+      } catch (ConfigurationException e) {
+        errors.merge(e.getErrorMessages());
        } catch (ErrorsException e) {
          errors.merge(e.getErrors());
        }

Modified: trunk/test/com/google/inject/BindingTest.java
==============================================================================
--- trunk/test/com/google/inject/BindingTest.java       (original)
+++ trunk/test/com/google/inject/BindingTest.java       Sun Jun 21 11:13:01 2009
@@ -216,38 +216,59 @@
      @Inject TooManyConstructors() {}
    }

-  public void testToConstructorBindings() throws NoSuchMethodException {
-    final Constructor constructor = C.class.getConstructor(Stage.class,  
Object.class);
+  public void testToConstructorBinding() throws NoSuchMethodException {
+    final Constructor<D> constructor = D.class.getConstructor(Stage.class);

      Injector injector = Guice.createInjector(new AbstractModule() {
        protected void configure() {
-        bind(new TypeLiteral<C<Stage>>() {}).toConstructor(constructor);
-        bind(new TypeLiteral<C<Injector>>() {}).toConstructor(constructor);
+        bind(Object.class).toConstructor(constructor);
        }
      });

-    C<Stage> one = injector.getInstance(new Key<C<Stage>>() {});
+    D d = (D) injector.getInstance(Object.class);
+    assertEquals(Stage.DEVELOPMENT, d.stage);
+  }
+
+  public void testToConstructorBindingsOnParameterizedTypes() throws  
NoSuchMethodException {
+    final Constructor<C> constructor = C.class.getConstructor(Stage.class,  
Object.class);
+    final Key<Object> s = new Key<Object>(named("s")) {};
+    final Key<Object> i = new Key<Object>(named("i")) {};
+
+    Injector injector = Guice.createInjector(new AbstractModule() {
+      protected void configure() {
+        bind(s).toConstructor(constructor, new TypeLiteral<C<Stage>>() {});
+        bind(i).toConstructor(constructor, new TypeLiteral<C<Injector>>()  
{});
+      }
+    });
+
+    C<Stage> one = (C<Stage>) injector.getInstance(s);
      assertEquals(Stage.DEVELOPMENT, one.stage);
      assertEquals(Stage.DEVELOPMENT, one.t);
      assertEquals(Stage.DEVELOPMENT, one.anotherT);

-    C<Injector> two = injector.getInstance(new Key<C<Injector>>() {});
+    C<Injector> two = (C<Injector>) injector.getInstance(i);
      assertEquals(Stage.DEVELOPMENT, two.stage);
      assertEquals(injector, two.t);
      assertEquals(injector, two.anotherT);
    }

-  public void testToConstructorBinding() throws NoSuchMethodException {
-    final Constructor<D> constructor = D.class.getConstructor(Stage.class);
-
-    Injector injector = Guice.createInjector(new AbstractModule() {
-      protected void configure() {
-        bind(Object.class).toConstructor(constructor);
-      }
-    });
+  public void testToConstructorBindingsFailsOnRawTypes() throws  
NoSuchMethodException {
+    final Constructor constructor = C.class.getConstructor(Stage.class,  
Object.class);

-    D d = (D) injector.getInstance(Object.class);
-    assertEquals(Stage.DEVELOPMENT, d.stage);
+    try {
+      Guice.createInjector(new AbstractModule() {
+        protected void configure() {
+          bind(Object.class).toConstructor(constructor);
+        }
+      });
+      fail();
+    } catch (CreationException expected) {
+      assertContains(expected.getMessage(),
+          "1) T cannot be used as a key; It is not fully specified.",
+          "at " + C.class.getName() + ".<init>(BindingTest.java:",
+          "2) T cannot be used as a key; It is not fully specified.",
+          "at " + C.class.getName() + ".anotherT(BindingTest.java:");
+    }
    }

    public void testToConstructorAndMethodInterceptors() throws  
NoSuchMethodException {

Modified: trunk/test/com/google/inject/spi/ElementsTest.java
==============================================================================
--- trunk/test/com/google/inject/spi/ElementsTest.java  (original)
+++ trunk/test/com/google/inject/spi/ElementsTest.java  Sun Jun 21 11:13:01  
2009
@@ -1080,20 +1080,37 @@
    }

    public void testBindToConstructor() throws NoSuchMethodException,  
NoSuchFieldException {
-    final Constructor<B> constructor =  
B.class.getDeclaredConstructor(Object.class);
+    final Constructor<A> aConstructor = A.class.getDeclaredConstructor();
+    final Constructor<B> bConstructor =  
B.class.getDeclaredConstructor(Object.class);
      final Field field = B.class.getDeclaredField("stage");

      checkModule(
          new AbstractModule() {
            protected void configure() {
-            bind(new TypeLiteral<B<Integer>>()  
{}).toConstructor((Constructor) constructor)
+            bind(A.class).toConstructor(aConstructor);
+            bind(B.class).toConstructor(bConstructor, new  
TypeLiteral<B<Integer>>() {})
                  .in(Singleton.class);
            }
          },

          new FailingElementVisitor() {
            @Override public <T> Void visit(Binding<T> binding) {
-            assertEquals(new Key<B<Integer>>() {}, binding.getKey());
+            assertEquals(new Key<A>() {}, binding.getKey());
+
+            return binding.acceptTargetVisitor(new  
FailingTargetVisitor<T>() {
+              @Override public Void visit(ConstructorBinding<? extends T>  
constructorBinding) {
+                InjectionPoint injectionPoint =  
constructorBinding.getConstructor();
+                assertEquals(aConstructor, injectionPoint.getMember());
+                assertEquals(new TypeLiteral<A>() {},  
injectionPoint.getDeclaringType());
+                return null;
+              }
+            });
+          }
+        },
+
+        new FailingElementVisitor() {
+          @Override public <T> Void visit(Binding<T> binding) {
+            assertEquals(new Key<B>() {}, binding.getKey());
              binding.acceptScopingVisitor(new  
FailingBindingScopingVisitor() {
                @Override public Void visitScopeAnnotation(Class<? extends  
Annotation> annotation) {
                  assertEquals(Singleton.class, annotation);
@@ -1103,7 +1120,7 @@

              binding.acceptTargetVisitor(new FailingTargetVisitor<T>() {
                @Override public Void visit(ConstructorBinding<? extends T>  
constructorBinding) {
-                assertEquals(constructor,  
constructorBinding.getConstructor().getMember());
+                assertEquals(bConstructor,  
constructorBinding.getConstructor().getMember());
                  assertEquals(Key.get(Integer.class),
                       
getOnlyElement(constructorBinding.getConstructor().getDependencies()).getKey());
                  assertEquals(field,

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"google-guice-dev" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/google-guice-dev?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to