Author: limpbizkit
Date: Sun Nov  2 00:59:13 2008
New Revision: 655

Modified:
     
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryProvider.java
     
trunk/extensions/assistedinject/test/com/google/inject/assistedinject/FactoryProviderTest.java
     
trunk/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java
     
trunk/extensions/multibindings/src/com/google/inject/multibindings/Multibinder.java
     
trunk/extensions/multibindings/test/com/google/inject/multibindings/MapBinderTest.java
     
trunk/extensions/multibindings/test/com/google/inject/multibindings/MultibinderTest.java
     
trunk/extensions/privatemodules/test/com/google/inject/privatemodules/PrivateModuleTest.java
    trunk/src/com/google/inject/InjectorImpl.java
    trunk/src/com/google/inject/ProviderToInternalFactoryAdapter.java
    trunk/src/com/google/inject/SingleParameterInjector.java
    trunk/src/com/google/inject/internal/Annotations.java
    trunk/src/com/google/inject/internal/Errors.java
    trunk/src/com/google/inject/spi/Elements.java
    trunk/test/com/google/inject/BinderTest.java
    trunk/test/com/google/inject/ImplicitBindingTest.java
    trunk/test/com/google/inject/InjectorTest.java
    trunk/test/com/google/inject/ProvisionExceptionTest.java
    trunk/test/com/google/inject/ScopesTest.java

Log:
Taking advantage of the error message changes in some extensions.

AssistedInject, PrivateModules and Multibindings now have nice messages  
that are integrated into the main CreationException.

Also tweaking the errors in Binder and Errors. If a module throws a  
ConfigurationException, that message will be embedded in the main  
CreationException message.

Modified:  
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryProvider.java
==============================================================================
---  
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryProvider.java
        
(original)
+++  
trunk/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryProvider.java
        
Sun Nov  2 00:59:13 2008
@@ -16,15 +16,18 @@

  package com.google.inject.assistedinject;

+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.inject.ConfigurationException;
  import com.google.inject.Inject;
  import com.google.inject.Injector;
  import com.google.inject.Provider;
+import com.google.inject.spi.Message;
  import java.lang.reflect.Constructor;
  import java.lang.reflect.InvocationHandler;
  import java.lang.reflect.Method;
  import java.lang.reflect.Proxy;
-import java.util.ArrayList;
-import java.util.HashMap;
  import java.util.List;
  import java.util.Map;

@@ -105,8 +108,7 @@

    @Inject
    @SuppressWarnings({"unchecked", "unused"})
-  private void setInjectorAndCheckUnboundParametersAreInjectable(
-      Injector injector) {
+  void setInjectorAndCheckUnboundParametersAreInjectable(Injector  
injector) {
      this.injector = injector;
      for (AssistedConstructor<?> c : factoryMethodToConstructor.values()) {
        for (Parameter p : c.getAllParameters()) {
@@ -114,22 +116,20 @@
            // this is lame - we're not using the proper mechanism to add an
            // error to the injector. Throughout this class we throw  
exceptions
            // to add errors, which isn't really the best way in Guice
-          throw new IllegalStateException(String.format(
-              "Parameter of type '%s' is not injectable or annotated "
-                + "with @Assisted for Constructor '%s'", p, c));
+          throw newConfigurationException("Parameter of type '%s' is not  
injectable or annotated "
+                + "with @Assisted for Constructor '%s'", p, c);
          }
        }
      }
    }
-
+
    private void checkDeclaredExceptionsMatch() {
      for (Map.Entry<Method, AssistedConstructor<?>> entry :  
factoryMethodToConstructor.entrySet()) {
        for (Class<?> constructorException :  
entry.getValue().getDeclaredExceptions()) {
          if (!isConstructorExceptionCompatibleWithFactoryExeception(
              constructorException, entry.getKey().getExceptionTypes())) {
-          throw new IllegalStateException(String.format(
-              "Constructor %s declares an exception, but no compatible  
exception is thrown "
-                  + "by the factory method %s", entry.getValue(),  
entry.getKey()));
+          throw newConfigurationException("Constructor %s declares an  
exception, but no compatible "
+              + "exception is thrown by the factory method %s",  
entry.getValue(), entry.getKey());
          }
        }
      }
@@ -152,37 +152,30 @@

    @SuppressWarnings({"unchecked"})
    private Map<Method, AssistedConstructor<?>> createMethodMapping() {
-
-    List<AssistedConstructor<?>> constructors = new  
ArrayList<AssistedConstructor<?>>();
-
+    List<AssistedConstructor<?>> constructors = Lists.newArrayList();
+
      for (Constructor c : implementationType.getDeclaredConstructors()) {
        if (c.getAnnotation(AssistedInject.class) != null) {
          constructors.add(new AssistedConstructor(c));
        }
      }
-
+
      if (constructors.size() != factoryType.getMethods().length) {
-      throw new IllegalArgumentException(
-          String.format(
-              "Constructor mismatch: %s has %s @AssistedInject " +
-              "constructors, factory %s has %s creation methods",
-              implementationType.getSimpleName(),
-              constructors.size(),
-              factoryType.getSimpleName(),
-              factoryType.getMethods().length));
-    }
-
-    Map<ParameterListKey, AssistedConstructor> paramsToConstructor
-        = new HashMap<ParameterListKey, AssistedConstructor>();
-
+      throw newConfigurationException("Constructor mismatch: %s has %s  
@AssistedInject "
+          + "constructors, factory %s has %s creation methods",  
implementationType.getSimpleName(),
+          constructors.size(), factoryType.getSimpleName(),  
factoryType.getMethods().length);
+    }
+
+    Map<ParameterListKey, AssistedConstructor> paramsToConstructor =  
Maps.newHashMap();
+
      for (AssistedConstructor c : constructors) {
        if (paramsToConstructor.containsKey(c.getAssistedParameters())) {
          throw new RuntimeException("Duplicate constructor, " + c);
        }
        paramsToConstructor.put(c.getAssistedParameters(), c);
      }
-
-    Map<Method, AssistedConstructor<?>> result = new HashMap<Method,  
AssistedConstructor<?>>();
+
+    Map<Method, AssistedConstructor<?>> result = Maps.newHashMap();
      for (Method method : factoryType.getMethods()) {
        if (!method.getReturnType().isAssignableFrom(implementationType)) {
          throw new RuntimeException(String.format("Return type of method  
\"%s\""
@@ -190,15 +183,14 @@
              implementationType.getName()));
        }
        ParameterListKey methodParams = new  
ParameterListKey(method.getGenericParameterTypes());
-
+
        if (!paramsToConstructor.containsKey(methodParams)) {
-        throw new IllegalArgumentException(String.format("%s has no " +
-            "@AssistInject constructor that takes the @Assisted  
parameters %s " +
-            "in that order. @AssistInject constructors are %s",
-            implementationType, methodParams,  
paramsToConstructor.values()));
+        throw newConfigurationException("%s has no @AssistInject  
constructor that takes the "
+            + "@Assisted parameters %s in that order. @AssistInject  
constructors are %s",
+            implementationType, methodParams,  
paramsToConstructor.values());
        }
        AssistedConstructor matchingConstructor =  
paramsToConstructor.remove(methodParams);
-
+
        result.put(method, matchingConstructor);
      }
      return result;
@@ -207,7 +199,6 @@
    @SuppressWarnings({"unchecked"})
    public F get() {
      InvocationHandler invocationHandler = new InvocationHandler() {
-
        public Object invoke(Object proxy, Method method, Object[]  
creationArgs) throws Throwable {
          // pass methods from Object.class to the proxy
          if (method.getDeclaringClass().equals(Object.class)) {
@@ -244,5 +235,9 @@

      return (F) Proxy.newProxyInstance(factoryType.getClassLoader(),
          new Class[] {factoryType}, invocationHandler);
+  }
+
+  private ConfigurationException newConfigurationException(String format,  
Object... args) {
+    return new ConfigurationException(ImmutableSet.of(new  
Message(String.format(format, args))));
    }
  }

Modified:  
trunk/extensions/assistedinject/test/com/google/inject/assistedinject/FactoryProviderTest.java
==============================================================================
---  
trunk/extensions/assistedinject/test/com/google/inject/assistedinject/FactoryProviderTest.java
   
(original)
+++  
trunk/extensions/assistedinject/test/com/google/inject/assistedinject/FactoryProviderTest.java
   
Sun Nov  2 00:59:13 2008
@@ -515,7 +515,7 @@
        fail();
      } catch (CreationException expected) {
        assertContains(expected.getMessage(),
-          "Parameter of type 'double' is not injectable or annotated with  
@Assisted");
+          "1) Parameter of type 'double' is not injectable or annotated  
with @Assisted");
      }
    }


Modified:  
trunk/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java
==============================================================================
---  
trunk/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java
        
(original)
+++  
trunk/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java
        
Sun Nov  2 00:59:13 2008
@@ -16,8 +16,6 @@

  package com.google.inject.multibindings;

-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
  import com.google.inject.Binder;
  import com.google.inject.Inject;
  import com.google.inject.Key;
@@ -26,6 +24,8 @@
  import com.google.inject.TypeLiteral;
  import com.google.inject.binder.LinkedBindingBuilder;
  import com.google.inject.multibindings.Multibinder.RealMultibinder;
+import static  
com.google.inject.multibindings.Multibinder.checkConfiguration;
+import static com.google.inject.multibindings.Multibinder.checkNotNull;
  import com.google.inject.util.Types;
  import java.lang.annotation.Annotation;
  import java.lang.reflect.Type;
@@ -223,7 +223,7 @@
       */
      @Override public LinkedBindingBuilder<V> addBinding(K key) {
        checkNotNull(key, "key");
-      checkState(!isInitialized(), "MapBinder was already initialized");
+      checkConfiguration(!isInitialized(), "MapBinder was already  
initialized");

        @SuppressWarnings("unchecked")
        Key<V> valueKey = (Key<V>) Key.get(valueType, new  
RealElement(entrySetBinder.getSetName()));
@@ -233,7 +233,7 @@
      }

      public void configure(Binder binder) {
-      checkState(!isInitialized(), "MapBinder was already initialized");
+      checkConfiguration(!isInitialized(), "MapBinder was already  
initialized");

        // binds a Map<K, Provider<V>> from a collection of Map<Entry<K,  
Provider<V>>
        final Provider<Set<Entry<K, Provider<V>>>> entrySetProvider = binder
@@ -247,7 +247,7 @@

            Map<K, Provider<V>> providerMapMutable = new LinkedHashMap<K,  
Provider<V>>();
            for (Entry<K, Provider<V>> entry : entrySetProvider.get()) {
-            checkState(providerMapMutable.put(entry.getKey(),  
entry.getValue()) == null,
+            checkConfiguration(providerMapMutable.put(entry.getKey(),  
entry.getValue()) == null,
                  "Map injection failed due to duplicated key \"%s\"",  
entry.getKey());
            }

@@ -266,7 +266,7 @@
            for (Entry<K, Provider<V>> entry : mapProvider.get().entrySet())  
{
              V value = entry.getValue().get();
              K key = entry.getKey();
-            checkState(value != null,
+            checkConfiguration(value != null,
                  "Map injection failed due to null value for key \"%s\"",  
key);
              map.put(key, value);
            }

Modified:  
trunk/extensions/multibindings/src/com/google/inject/multibindings/Multibinder.java
==============================================================================
---  
trunk/extensions/multibindings/src/com/google/inject/multibindings/Multibinder.java
      
(original)
+++  
trunk/extensions/multibindings/src/com/google/inject/multibindings/Multibinder.java
      
Sun Nov  2 00:59:13 2008
@@ -16,10 +16,11 @@

  package com.google.inject.multibindings;

-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
  import com.google.inject.Binder;
  import com.google.inject.Binding;
+import com.google.inject.ConfigurationException;
  import com.google.inject.Inject;
  import com.google.inject.Injector;
  import com.google.inject.Key;
@@ -27,6 +28,7 @@
  import com.google.inject.Provider;
  import com.google.inject.TypeLiteral;
  import com.google.inject.binder.LinkedBindingBuilder;
+import com.google.inject.spi.Message;
  import com.google.inject.util.Types;
  import java.lang.annotation.Annotation;
  import java.lang.reflect.Type;
@@ -183,14 +185,14 @@

      @SuppressWarnings("unchecked")
      public void configure(Binder binder) {
-      checkState(!isInitialized(), "Multibinder was already initialized");
+      checkConfiguration(!isInitialized(), "Multibinder was already  
initialized");

        binder.bind(setKey).toProvider(this);
      }

      @SuppressWarnings("unchecked")
      @Override public LinkedBindingBuilder<T> addBinding() {
-      checkState(!isInitialized(), "Multibinder was already initialized");
+      checkConfiguration(!isInitialized(), "Multibinder was already  
initialized");

        return binder.bind((Key<T>) Key.get(elementType, new  
RealElement(setName)));
      }
@@ -224,13 +226,13 @@
      }

      public Set<T> get() {
-      checkState(isInitialized(), "Multibinder is not initialized");
+      checkConfiguration(isInitialized(), "Multibinder is not  
initialized");

        Set<T> result = new LinkedHashSet<T>();
        for (Provider<T> provider : providers) {
          final T newValue = provider.get();
-        checkState(newValue != null, "Set injection failed due to null  
element");
-        checkState(result.add(newValue),
+        checkConfiguration(newValue != null, "Set injection failed due to  
null element");
+        checkConfiguration(result.add(newValue),
              "Set injection failed due to duplicated element \"%s\"",  
newValue);
        }
        return Collections.unmodifiableSet(result);
@@ -266,5 +268,23 @@
      public Type getElementType() {
        return elementType;
      }
+  }
+
+  static void checkConfiguration(boolean condition, String format,  
Object... args) {
+    if (condition) {
+      return;
+    }
+
+    throw new ConfigurationException(ImmutableSet.of(new  
Message(String.format(format, args))));
+  }
+
+  static <T> T checkNotNull(T reference, String name) {
+    if (reference != null) {
+      return reference;
+    }
+
+    NullPointerException npe = new NullPointerException(name);
+    throw new ConfigurationException(ImmutableSet.of(
+        new Message(ImmutableList.of(), npe.toString(), npe)));
    }
  }

Modified:  
trunk/extensions/multibindings/test/com/google/inject/multibindings/MapBinderTest.java
==============================================================================
---  
trunk/extensions/multibindings/test/com/google/inject/multibindings/MapBinderTest.java
   
(original)
+++  
trunk/extensions/multibindings/test/com/google/inject/multibindings/MapBinderTest.java
   
Sun Nov  2 00:59:13 2008
@@ -250,8 +250,8 @@
        injector.getInstance(Key.get(mapOfString));
        fail();
      } catch(ProvisionException expected) {
-      assertEquals("Map injection failed due to null value for key  
\"null\"",
-          expected.getCause().getMessage());
+      assertContains(expected.getMessage(),
+          "1) Map injection failed due to null value for key \"null\"");
      }
    }


Modified:  
trunk/extensions/multibindings/test/com/google/inject/multibindings/MultibinderTest.java
==============================================================================
---  
trunk/extensions/multibindings/test/com/google/inject/multibindings/MultibinderTest.java
         
(original)
+++  
trunk/extensions/multibindings/test/com/google/inject/multibindings/MultibinderTest.java
         
Sun Nov  2 00:59:13 2008
@@ -219,8 +219,8 @@
        injector.getInstance(Key.get(setOfString));
        fail();
      } catch(ProvisionException expected) {
-      assertEquals("Set injection failed due to duplicated element \"A\"",
-          expected.getCause().getMessage());
+      assertContains(expected.getMessage(),
+          "1) Set injection failed due to duplicated element \"A\"");
      }
    }

@@ -236,8 +236,8 @@
        injector.getInstance(Key.get(setOfString));
        fail();
      } catch(ProvisionException expected) {
-      assertEquals("Set injection failed due to null element",
-          expected.getCause().getMessage());
+      assertContains(expected.getMessage(),
+          "1) Set injection failed due to null element");
      }
    }


Modified:  
trunk/extensions/privatemodules/test/com/google/inject/privatemodules/PrivateModuleTest.java
==============================================================================
---  
trunk/extensions/privatemodules/test/com/google/inject/privatemodules/PrivateModuleTest.java
     
(original)
+++  
trunk/extensions/privatemodules/test/com/google/inject/privatemodules/PrivateModuleTest.java
     
Sun Nov  2 00:59:13 2008
@@ -150,6 +150,37 @@
      }
    }

+  /**
+   * Ensure that when we've got errors in different private modules, Guice  
presents all errors
+   * in a unified message.
+   */
+  public void testMessagesFromPrivateModulesAreNicelyIntegrated() {
+    try {
+      Guice.createInjector(
+          new PrivateModule() {
+            public void configurePrivateBindings() {
+              bind(C.class);
+            }
+          },
+          new PrivateModule() {
+            public void configurePrivateBindings() {
+              bind(AB.class);
+            }
+          }
+      );
+      fail();
+    } catch (CreationException expected) {
+      assertContains(expected.getMessage(),
+          "1) No implementation for " + C.class.getName() + " was bound.",
+          "at " +  
getClass().getName(), ".configurePrivateBindings(PrivateModuleTest.java:",
+          "2) No implementation for " +  
String.class.getName(), "Named(value=a) was bound.",
+          "for field at " + AB.class.getName()  
+ ".a(PrivateModuleTest.java:",
+          "3) No implementation for " +  
String.class.getName(), "Named(value=b) was bound.",
+          "for field at " + AB.class.getName()  
+ ".b(PrivateModuleTest.java:",
+          "3 errors");
+    }
+  }
+
    public void testNestedPrivateInjectors() {
      Injector injector = Guice.createInjector(new PrivateModule() {
        public void configurePrivateBindings() {

Modified: trunk/src/com/google/inject/InjectorImpl.java
==============================================================================
--- trunk/src/com/google/inject/InjectorImpl.java       (original)
+++ trunk/src/com/google/inject/InjectorImpl.java       Sun Nov  2 00:59:13 2008
@@ -329,8 +329,7 @@
          // TODO: does this put the binding in JIT bindings?
          binding.initialize(this, errors);
          successful = true;
-      }
-      finally {
+      } finally {
          if (!successful) {
            jitBindings.remove(key);
          }
@@ -580,6 +579,7 @@
        = new FailableCache<Class<?>, ImmutableList<SingleMemberInjector>>()  
{
      protected ImmutableList<SingleMemberInjector> create(Class<?> type,  
Errors errors)
          throws ErrorsException {
+      int numErrorsBefore = errors.size();
        List<InjectionPoint> injectionPoints = Lists.newArrayList();
        try {
          InjectionPoint.addForInstanceMethodsAndFields(type,  
injectionPoints);
@@ -587,7 +587,7 @@
          errors.merge(e.getErrorMessages());
        }
        ImmutableList<SingleMemberInjector> injectors =  
getInjectors(injectionPoints, errors);
-      errors.throwIfNecessary();
+      errors.throwIfNewErrors(numErrorsBefore);
        return injectors;
      }
    };
@@ -644,6 +644,7 @@
        return null;
      }

+    int numErrorsBefore = errors.size();
      SingleParameterInjector<?>[] result = new  
SingleParameterInjector<?>[parameters.size()];
      int i = 0;
      for (Dependency<?> parameter : parameters) {
@@ -654,7 +655,7 @@
        }
      }

-    errors.throwIfNecessary();
+    errors.throwIfNewErrors(numErrorsBefore);
      return ImmutableList.of(result);
    }

@@ -746,7 +747,7 @@
                }
              }
            });
-          errors.throwIfNecessary();
+          errors.throwIfNewErrors(0);
            return t;
          } catch (ErrorsException e) {
            throw new  
ProvisionException(errors.merge(e.getErrors()).getMessages());
@@ -763,7 +764,7 @@
      Errors errors = new Errors(key);
      try {
        Provider<T> result = getProviderOrThrow(key, errors);
-      errors.throwIfNecessary();
+      errors.throwIfNewErrors(0);
        return result;
      } catch (ErrorsException e) {
        throw new  
ConfigurationException(errors.merge(e.getErrors()).getMessages());

Modified: trunk/src/com/google/inject/ProviderToInternalFactoryAdapter.java
==============================================================================
--- trunk/src/com/google/inject/ProviderToInternalFactoryAdapter.java    
(original)
+++ trunk/src/com/google/inject/ProviderToInternalFactoryAdapter.java   Sun  
Nov  2 00:59:13 2008
@@ -43,7 +43,7 @@
            return internalFactory.get(errors, context, dependency);
          }
        });
-      errors.throwIfNecessary();
+      errors.throwIfNewErrors(0);
        return t;
      } catch (ErrorsException e) {
        throw new  
ProvisionException(errors.merge(e.getErrors()).getMessages());

Modified: trunk/src/com/google/inject/SingleParameterInjector.java
==============================================================================
--- trunk/src/com/google/inject/SingleParameterInjector.java    (original)
+++ trunk/src/com/google/inject/SingleParameterInjector.java    Sun Nov  2  
00:59:13 2008
@@ -51,6 +51,7 @@
        return null;
      }

+    int numErrorsBefore = errors.size();
      Object[] parameters = new Object[parameterInjectors.size()];

      int i = 0;
@@ -62,7 +63,7 @@
        }
      }

-    errors.throwIfNecessary();
+    errors.throwIfNewErrors(numErrorsBefore);
      return parameters;
    }
  }

Modified: trunk/src/com/google/inject/internal/Annotations.java
==============================================================================
--- trunk/src/com/google/inject/internal/Annotations.java       (original)
+++ trunk/src/com/google/inject/internal/Annotations.java       Sun Nov  2  
00:59:13 2008
@@ -85,8 +85,9 @@
    /** Gets a key for the given type, member and annotations. */
    public static Key<?> getKey(Type type, Member member, Annotation[]  
annotations, Errors errors)
        throws ErrorsException {
+    int numErrorsBefore = errors.size();
      Annotation found = findBindingAnnotation(errors, member, annotations);
-    errors.throwIfNecessary();
+    errors.throwIfNewErrors(numErrorsBefore);
      return found == null ? Key.get(type) : Key.get(type, found);
    }


Modified: trunk/src/com/google/inject/internal/Errors.java
==============================================================================
--- trunk/src/com/google/inject/internal/Errors.java    (original)
+++ trunk/src/com/google/inject/internal/Errors.java    Sun Nov  2 00:59:13  
2008
@@ -17,6 +17,7 @@
  package com.google.inject.internal;

  import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
  import com.google.common.collect.Lists;
  import com.google.inject.ConfigurationException;
  import com.google.inject.CreationException;
@@ -35,7 +36,6 @@
  import java.lang.reflect.Constructor;
  import java.lang.reflect.Field;
  import java.lang.reflect.Member;
-import java.lang.reflect.Type;
  import java.util.Collection;
  import java.util.Collections;
  import java.util.Comparator;
@@ -261,16 +261,23 @@
      return errorInUserCode("Error in custom provider, %s",  
runtimeException);
    }

-  public Errors errorInUserCode(String message, Throwable cause) {
-    if (cause instanceof ProvisionException) {
-      return merge(((ProvisionException) cause).getErrorMessages());
-
-    } else if (cause instanceof ConfigurationException) {
-      return merge(((ConfigurationException) cause).getErrorMessages());
+  public static Collection<Message> getMessagesFromThrowable(Throwable  
throwable) {
+    if (throwable instanceof ProvisionException) {
+      return ((ProvisionException) throwable).getErrorMessages();
+    } else if (throwable instanceof ConfigurationException) {
+      return ((ConfigurationException) throwable).getErrorMessages();
+    } else if (throwable instanceof CreationException) {
+      return ((CreationException) throwable).getErrorMessages();
+    } else {
+      return ImmutableSet.of();
+    }
+  }

-    } else if (cause instanceof CreationException) {
-      return merge(((CreationException) cause).getErrorMessages());
+  public Errors errorInUserCode(String message, Throwable cause) {
+    Collection<Message> messages = getMessagesFromThrowable(cause);

+    if (!messages.isEmpty()) {
+      return merge(messages);
      } else {
        return addMessage(cause, message, cause);
      }
@@ -336,13 +343,15 @@
    public List<Object> getSources() {
      List<Object> sources = Lists.newArrayList();
      for (Errors e = this; e != null; e = e.parent) {
-      sources.add(0, e.source);
+      if (e.source != SourceProvider.UNKNOWN_SOURCE) {
+        sources.add(0, e.source);
+      }
      }
      return sources;
    }

-  public void throwIfNecessary() throws ErrorsException {
-    if (!hasErrors()) {
+  public void throwIfNewErrors(int expectedSize) throws ErrorsException {
+    if (size() == expectedSize) {
        return;
      }

@@ -469,6 +478,10 @@
      return onlyCause;
    }

+  public int size() {
+    return errors.size();
+  }
+
    private static abstract class Converter<T> {

      final Class<T> type;
@@ -540,18 +553,8 @@

      } else if (source instanceof Key) {
        Key<?> key = (Key<?>) source;
-      Type type = key.getTypeLiteral().getType();
-      if (key.getAnnotationType() != null) {
-        formatter.format("  at binding for %s annotated with %s%n",  
MoreTypes.toString(type),
-            (key.getAnnotation() != null ? key.getAnnotation() :  
key.getAnnotationType()));
-
-      } else if (type instanceof Class) {
-        formatter.format("  at binding for %s%n",  
StackTraceElements.forType((Class<?>) type));
+      formatter.format("  while locating %s%n", convert(key));

-      } else {
-          formatter.format("  at binding for %s%n", type);
-
-      }
      } else {
        formatter.format("  at %s%n", source);
      }
@@ -563,10 +566,13 @@
      Class<? extends Member> memberType = MoreTypes.memberType(member);

      if (memberType == Field.class) {
-      formatter.format("  for field at %s%n",  
StackTraceElements.forMember(member));
+      dependency = injectionPoint.getDependencies().get(0);
+      formatter.format("  while locating %s%n",  
convert(dependency.getKey()));
+      formatter.format("    for field at %s%n",  
StackTraceElements.forMember(member));

      } else if (dependency != null) {
-      formatter.format("  for parameter %s at %s%n",
+      formatter.format("  while locating %s%n",  
convert(dependency.getKey()));
+      formatter.format("    for parameter %s at %s%n",
            dependency.getParameterIndex(),  
StackTraceElements.forMember(member));

      } else {

Modified: trunk/src/com/google/inject/spi/Elements.java
==============================================================================
--- trunk/src/com/google/inject/spi/Elements.java       (original)
+++ trunk/src/com/google/inject/spi/Elements.java       Sun Nov  2 00:59:13 2008
@@ -31,6 +31,7 @@
  import com.google.inject.TypeLiteral;
  import com.google.inject.binder.AnnotatedBindingBuilder;
  import com.google.inject.binder.AnnotatedConstantBindingBuilder;
+import com.google.inject.internal.Errors;
  import com.google.inject.internal.ModuleBinding;
  import com.google.inject.internal.ProviderMethodsModule;
  import com.google.inject.internal.SourceProvider;
@@ -41,6 +42,7 @@
  import java.util.Collections;
  import java.util.List;
  import java.util.Set;
+import java.util.Collection;
  import org.aopalliance.intercept.MethodInterceptor;

  /**
@@ -156,7 +158,12 @@
          try {
            module.configure(this);
          } catch (RuntimeException e) {
-          addError(e);
+          Collection<Message> messages =  
Errors.getMessagesFromThrowable(e);
+          if (!messages.isEmpty()) {
+            elements.addAll(messages);
+          } else {
+            addError(e);
+          }
          }
          install(ProviderMethodsModule.forModule(module));
        }

Modified: trunk/test/com/google/inject/BinderTest.java
==============================================================================
--- trunk/test/com/google/inject/BinderTest.java        (original)
+++ trunk/test/com/google/inject/BinderTest.java        Sun Nov  2 00:59:13 2008
@@ -416,7 +416,7 @@
      } catch (ConfigurationException expected) {
        Asserts.assertContains(expected.getMessage(),
            "1) Cannot inject a Provider that has no type parameter",
-          "at binding for " + Provider.class.getName());
+          "while locating " + Provider.class.getName());
      }
    }
  }

Modified: trunk/test/com/google/inject/ImplicitBindingTest.java
==============================================================================
--- trunk/test/com/google/inject/ImplicitBindingTest.java       (original)
+++ trunk/test/com/google/inject/ImplicitBindingTest.java       Sun Nov  2  
00:59:13 2008
@@ -90,7 +90,7 @@
        Asserts.assertContains(expected.getMessage(),
            "1) No implementation for " + I.class.getName(),
            "annotated with @" + Named.class.getName() + "(value=i) was  
bound.",
-          "at binding for " + I.class.getName(),
+          "while locating " + I.class.getName(),
            " annotated with @" + Named.class.getName() + "(value=i)");
      }
    }

Modified: trunk/test/com/google/inject/InjectorTest.java
==============================================================================
--- trunk/test/com/google/inject/InjectorTest.java      (original)
+++ trunk/test/com/google/inject/InjectorTest.java      Sun Nov  2 00:59:13 2008
@@ -324,7 +324,8 @@
      } catch (ProvisionException expected) {
        assertContains(expected.getMessage(),
            Tree.class.getName() + " doesn't provide instances of " +  
Money.class.getName(),
-          "at ", Money.class.getName() + ".class(InjectorTest.java:");
+          "while locating ", Tree.class.getName(),
+          "while locating ", Money.class.getName());
      }
    }

@@ -335,7 +336,7 @@
      } catch (ConfigurationException expected) {
        assertContains(expected.getMessage(),
            Tree.class.getName() + " doesn't extend " +  
PineTree.class.getName(),
-          "at ", PineTree.class.getName() + ".class(InjectorTest.java:");
+          "while locating ", PineTree.class.getName());
      }
    }

@@ -346,7 +347,7 @@
      } catch (ConfigurationException expected) {
        assertContains(expected.getMessage(),
            "@ImplementedBy points to the same class it annotates.",
-          "at ", SeaHorse.class.getName() + ".class(InjectorTest.java:");
+          "while locating ", SeaHorse.class.getName());
      }
    }

@@ -357,7 +358,7 @@
      } catch (ConfigurationException expected) {
        assertContains(expected.getMessage(),
            "@ProvidedBy points to the same class it annotates",
-          "at ", Chicken.class.getName() + ".class(InjectorTest.java:");
+          "while locating ", Chicken.class.getName());
      }
    }


Modified: trunk/test/com/google/inject/ProvisionExceptionTest.java
==============================================================================
--- trunk/test/com/google/inject/ProvisionExceptionTest.java    (original)
+++ trunk/test/com/google/inject/ProvisionExceptionTest.java    Sun Nov  2  
00:59:13 2008
@@ -119,8 +119,8 @@
        fail();
      } catch (ProvisionException e) {
        assertContains(e.getMessage(), "1) User Exception",
-          "at binding for ",  
FProvider.class.getName(), ".class(ProvisionExceptionTest.java",
-          "at binding for ",  
F.class.getName(), ".class(ProvisionExceptionTest.java:");
+          "while locating ", FProvider.class.getName(),
+          "while locating ", F.class.getName());
      }
    }

@@ -170,7 +170,7 @@
      } catch (Exception expected) {
        assertContains(expected.getMessage(),
            "Injecting into inner classes is not supported.",
-          "at binding for " + InnerClass.class.getName()  
+ ".class(ProvisionExceptionTest.java:");
+          "while locating " + InnerClass.class.getName());
      }
    }

@@ -184,19 +184,20 @@
      } catch (Exception expected) {
        assertContains(expected.getMessage(),
            "Injecting into inner classes is not supported.",
-          "at binding for " + LocalClass.class.getName()  
+ ".class(ProvisionExceptionTest.java:");
+          "while locating " + LocalClass.class.getName());
      }
    }

    public void testBindingAnnotationsOnMethodsAndConstructors() {
      try {
-       
Guice.createInjector().getInstance(MethodWithBindingAnnotation.class);
+      Injector injector = Guice.createInjector();
+      injector.getInstance(MethodWithBindingAnnotation.class);
        fail();
      } catch (ConfigurationException expected) {
        assertContains(expected.getMessage(),  
MethodWithBindingAnnotation.class.getName()
            + ".injectMe() is annotated with @", Green.class.getName()  
+ "(), ",
            "but binding annotations should be applied to its parameters  
instead.",
-          "at binding for " + MethodWithBindingAnnotation.class.getName()  
+ ".class");
+          "while locating " + MethodWithBindingAnnotation.class.getName());
      }

      try {
@@ -207,7 +208,7 @@
            + ".<init>() is annotated with @", Green.class.getName()  
+ "(), ",
            "but binding annotations should be applied to its parameters  
instead.",
            "at " + ConstructorWithBindingAnnotation.class.getName()  
+ ".class",
-          "at binding for " +  
ConstructorWithBindingAnnotation.class.getName() + ".class");
+          "while locating " +  
ConstructorWithBindingAnnotation.class.getName());
      }
    }

@@ -224,8 +225,8 @@
      } catch (ProvisionException expected) {
        assertContains(expected.getMessage(),
            "at " + RealD.class.getName()  
+ ".<init>(ProvisionExceptionTest.java:",
-          "at binding for " + RealD.class.getName()  
+ ".class(ProvisionExceptionTest.java:",
-          "at binding for " + D.class.getName()  
+ ".class(ProvisionExceptionTest.java:");
+          "while locating " + RealD.class.getName(),
+          "while locating " + D.class.getName());
      }
    }

@@ -241,8 +242,8 @@
        fail();
      } catch (ProvisionException expected) {
        assertContains(expected.getMessage(),
-          "at binding for " + DProvider.class.getName()  
+ ".class(ProvisionExceptionTest.java:",
-          "at binding for " + D.class.getName()  
+ ".class(ProvisionExceptionTest.java:");
+          "while locating " + DProvider.class.getName(),
+          "while locating " + D.class.getName());
      }
    }


Modified: trunk/test/com/google/inject/ScopesTest.java
==============================================================================
--- trunk/test/com/google/inject/ScopesTest.java        (original)
+++ trunk/test/com/google/inject/ScopesTest.java        Sun Nov  2 00:59:13 2008
@@ -306,7 +306,7 @@
      } catch (ConfigurationException expected) {
        assertContains(expected.getMessage(),
            "1) More than one scope annotation was found: ",
-          "at binding for " +  
SingletonAndCustomScoped.class.getName(), ".class(ScopesTest.java:");
+          "while locating binding for " +  
SingletonAndCustomScoped.class.getName());
      }
    }


--~--~---------~--~----~------------~-------~--~----~
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