Author: limpbizkit
Date: Fri May 15 00:10:43 2009
New Revision: 946

Added:
    trunk/src/com/google/inject/internal/ExposureBuilder.java
    trunk/test/com/google/inject/util/NoopOverrideTest.java
       - copied, changed from r936,  
/trunk/test/com/google/inject/spi/ElementApplyToTest.java
Removed:
    trunk/src/com/google/inject/spi/ModuleWriter.java
    trunk/test/com/google/inject/spi/ModuleWriterTest.java
Modified:
    trunk/src/com/google/inject/BindingProcessor.java
    trunk/src/com/google/inject/internal/BindingBuilder.java
    trunk/src/com/google/inject/internal/LinkedProviderBindingImpl.java
    trunk/src/com/google/inject/internal/PrivateElementsImpl.java
    trunk/src/com/google/inject/spi/BindingTargetVisitor.java
    trunk/src/com/google/inject/spi/Elements.java
    trunk/src/com/google/inject/spi/PrivateElements.java
    trunk/src/com/google/inject/util/Modules.java
    trunk/test/com/google/inject/AllTests.java
    trunk/test/com/google/inject/OverrideModuleTest.java
    trunk/test/com/google/inject/PrivateModuleTest.java
    trunk/test/com/google/inject/spi/ElementApplyToTest.java
    trunk/test/com/google/inject/spi/ElementsTest.java
    trunk/test/com/google/inject/spi/ModuleRewriterTest.java

Log:
Killing ModuleWriter in favour of Element.applyTo()

Also fixing Modules.override() to interop nicely with private modules. Plus  
some new tests. Yay!

Modified: trunk/src/com/google/inject/BindingProcessor.java
==============================================================================
--- trunk/src/com/google/inject/BindingProcessor.java   (original)
+++ trunk/src/com/google/inject/BindingProcessor.java   Fri May 15 00:10:43  
2009
@@ -178,12 +178,7 @@
        }

        public Void visit(ExposedBinding<? extends T> binding) {
-        PrivateElements privateElements = binding.getPrivateElements();
-        ExposedKeyFactory<T> exposedKeyFactory = new  
ExposedKeyFactory<T>(key, privateElements);
-        creationListeners.add(exposedKeyFactory);
-        putBinding(new ExposedBindingImpl<T>(
-            injector, source, key, exposedKeyFactory, privateElements));
-        return null;
+        throw new IllegalArgumentException("Cannot apply a non-module  
element");
        }

        public Void visit(ConvertedConstantBinding<? extends T> binding) {
@@ -200,6 +195,20 @@
      });

      return true;
+  }
+
+  @Override public Boolean visit(PrivateElements privateElements) {
+    for (Key<?> key : privateElements.getExposedKeys()) {
+      bindExposed(privateElements, key);
+    }
+    return false; // leave the private elements for the  
PrivateElementsProcessor to handle
+  }
+
+  private <T> void bindExposed(PrivateElements privateElements, Key<T>  
key) {
+    ExposedKeyFactory<T> exposedKeyFactory = new ExposedKeyFactory<T>(key,  
privateElements);
+    creationListeners.add(exposedKeyFactory);
+    putBinding(new ExposedBindingImpl<T>(
+        injector, privateElements.getExposedSource(key), key,  
exposedKeyFactory, privateElements));
    }

    private <T> void validateKey(Object source, Key<T> key) {

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    Fri May 15  
00:10:43 2009
@@ -22,12 +22,10 @@
  import com.google.inject.Provider;
  import com.google.inject.TypeLiteral;
  import com.google.inject.binder.AnnotatedBindingBuilder;
-import com.google.inject.binder.AnnotatedElementBuilder;
  import static com.google.inject.internal.Preconditions.checkNotNull;
  import com.google.inject.spi.Element;
  import com.google.inject.spi.InjectionPoint;
  import com.google.inject.spi.Message;
-import com.google.inject.spi.PrivateElements;
  import java.lang.annotation.Annotation;
  import java.util.List;
  import java.util.Set;
@@ -130,48 +128,7 @@
      return this;
    }

-  public ExposureBuilder<T> usingKeyFrom(PrivateElements privateElements) {
-    checkNotTargetted();
-    checkNotScoped();
-
-    BindingImpl<T> base = getBinding();
-    ExposedBindingImpl<T> exposedBinding = new ExposedBindingImpl<T>(
-        base.getSource(), base.getKey(), base.getScoping(),  
privateElements);
-    setBinding(exposedBinding);
-
-    return new ExposureBuilder<T>(this, exposedBinding);
-  }
-
    @Override public String toString() {
      return "BindingBuilder<" + getBinding().getKey().getTypeLiteral()  
+ ">";
-  }
-
-  /**
-   * For private binder's expose() method.
-   */
-  public static class ExposureBuilder<T> implements  
AnnotatedElementBuilder {
-    private final BindingBuilder<T> bindingBuilder;
-    private BindingImpl<T> binding;
-
-    public ExposureBuilder(BindingBuilder<T> bindingBuilder,  
ExposedBindingImpl<T> binding) {
-      this.binding = binding;
-      this.bindingBuilder = bindingBuilder;
-    }
-
-    public void annotatedWith(Class<? extends Annotation> annotationType) {
-      binding = bindingBuilder.annotatedWithInternal(annotationType);
-    }
-
-    public void annotatedWith(Annotation annotation) {
-      binding = bindingBuilder.annotatedWithInternal(annotation);
-    }
-
-    public Key<?> getKey() {
-      return binding.getKey();
-    }
-
-    @Override public String toString() {
-      return "AnnotatedElementBuilder";
-    }
    }
  }

Added: trunk/src/com/google/inject/internal/ExposureBuilder.java
==============================================================================
--- (empty file)
+++ trunk/src/com/google/inject/internal/ExposureBuilder.java   Fri May 15  
00:10:43 2009
@@ -0,0 +1,67 @@
+/**
+ * Copyright (C) 2009 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.inject.internal;
+
+import com.google.inject.binder.AnnotatedElementBuilder;
+import com.google.inject.Binder;
+import com.google.inject.Key;
+import java.lang.annotation.Annotation;
+
+/**
+ * For private binder's expose() method.
+ */
+public class ExposureBuilder<T> implements AnnotatedElementBuilder {
+  private final Binder binder;
+  private final Object source;
+  private Key<T> key;
+
+  public ExposureBuilder(Binder binder, Object source, Key<T> key) {
+    this.binder = binder;
+    this.source = source;
+    this.key = key;
+  }
+
+  protected void checkNotAnnotated() {
+    if (key.getAnnotationType() != null) {
+      binder.addError(AbstractBindingBuilder.ANNOTATION_ALREADY_SPECIFIED);
+    }
+  }
+
+  public void annotatedWith(Class<? extends Annotation> annotationType) {
+     
com.google.inject.internal.Preconditions.checkNotNull(annotationType, 
"annotationType");
+    checkNotAnnotated();
+    key = Key.get(key.getTypeLiteral(), annotationType);
+  }
+
+  public void annotatedWith(Annotation annotation) {
+     
com.google.inject.internal.Preconditions.checkNotNull(annotation, "annotation");
+    checkNotAnnotated();
+    key = Key.get(key.getTypeLiteral(), annotation);
+  }
+
+  public Key<?> getKey() {
+    return key;
+  }
+
+  public Object getSource() {
+    return source;
+  }
+
+  @Override public String toString() {
+    return "AnnotatedElementBuilder";
+  }
+}
\ No newline at end of file

Modified:  
trunk/src/com/google/inject/internal/LinkedProviderBindingImpl.java
==============================================================================
--- trunk/src/com/google/inject/internal/LinkedProviderBindingImpl.java  
(original)
+++ trunk/src/com/google/inject/internal/LinkedProviderBindingImpl.java Fri  
May 15 00:10:43 2009
@@ -58,7 +58,8 @@
    }

    public void applyTo(Binder binder) {
-     
getScoping().applyTo(binder.bind(getKey()).toProvider(getProviderKey()));
+    getScoping().applyTo(binder.withSource(getSource())
+        .bind(getKey()).toProvider(getProviderKey()));
    }

    @Override public String toString() {

Modified: trunk/src/com/google/inject/internal/PrivateElementsImpl.java
==============================================================================
--- trunk/src/com/google/inject/internal/PrivateElementsImpl.java       
(original)
+++ trunk/src/com/google/inject/internal/PrivateElementsImpl.java       Fri May 
 
15 00:10:43 2009
@@ -16,16 +16,18 @@

  package com.google.inject.internal;

+import com.google.inject.Binder;
  import com.google.inject.Injector;
  import com.google.inject.Key;
-import com.google.inject.Binder;
-import com.google.inject.internal.BindingBuilder.ExposureBuilder;
+import com.google.inject.PrivateBinder;
+import static com.google.inject.internal.Preconditions.checkArgument;
  import static com.google.inject.internal.Preconditions.checkNotNull;
  import static com.google.inject.internal.Preconditions.checkState;
  import com.google.inject.spi.Element;
  import com.google.inject.spi.ElementVisitor;
  import com.google.inject.spi.PrivateElements;
  import java.util.List;
+import java.util.Map;
  import java.util.Set;

  /**
@@ -48,7 +50,7 @@
    private ImmutableList<Element> elements;

    /** lazily instantiated */
-  private ImmutableSet<Key<?>> exposedKeys;
+  private ImmutableMap<Key<?>, Object> exposedKeysToSources;
    private Injector injector;

    public PrivateElementsImpl(Object source) {
@@ -78,16 +80,16 @@
    }

    public Set<Key<?>> getExposedKeys() {
-    if (exposedKeys == null) {
-      Set<Key<?>> exposedKeysMutable = Sets.newLinkedHashSet();
+    if (exposedKeysToSources == null) {
+      Map<Key<?>, Object> exposedKeysToSourcesMutable =  
Maps.newLinkedHashMap();
        for (ExposureBuilder<?> exposureBuilder : exposureBuilders) {
-        exposedKeysMutable.add(exposureBuilder.getKey());
+        exposedKeysToSourcesMutable.put(exposureBuilder.getKey(),  
exposureBuilder.getSource());
        }
-      exposedKeys = ImmutableSet.copyOf(exposedKeysMutable);
+      exposedKeysToSources =  
ImmutableMap.copyOf(exposedKeysToSourcesMutable);
        exposureBuilders = null;
      }

-    return exposedKeys;
+    return exposedKeysToSources.keySet();
    }

    public <T> T acceptVisitor(ElementVisitor<T> visitor) {
@@ -103,6 +105,29 @@
    }

    public void applyTo(Binder binder) {
-    throw new UnsupportedOperationException("TODO");
+    PrivateBinder privateBinder =  
binder.withSource(source).newPrivateBinder();
+
+    for (Element element : getElements()) {
+      element.applyTo(privateBinder);
+    }
+
+    getExposedKeys(); // ensure exposedKeysToSources is populated
+    for (Map.Entry<Key<?>, Object> entry :  
exposedKeysToSources.entrySet()) {
+      privateBinder.withSource(entry.getValue()).expose(entry.getKey());
+    }
+  }
+
+  public Object getExposedSource(Key<?> key) {
+    getExposedKeys(); // ensure exposedKeysToSources is populated
+    Object source = exposedKeysToSources.get(key);
+    checkArgument(source != null, "%s not exposed by %s.", key, this);
+    return source;
+  }
+
+  @Override public String toString() {
+    return new ToStringBuilder(PrivateElements.class)
+        .add("exposedKeys", getExposedKeys())
+        .add("source", getSource())
+        .toString();
    }
  }

Modified: trunk/src/com/google/inject/spi/BindingTargetVisitor.java
==============================================================================
--- trunk/src/com/google/inject/spi/BindingTargetVisitor.java   (original)
+++ trunk/src/com/google/inject/spi/BindingTargetVisitor.java   Fri May 15  
00:10:43 2009
@@ -51,8 +51,8 @@
    V visit(LinkedKeyBinding<? extends T> binding);

    /**
-   * Visit a binding to a key exposed from an enclosed private  
environment. This target is found in
-   * both module and injector bindings.
+   * Visit a binding to a key exposed from an enclosed private  
environment. This target is only
+   * found in injector bindings.
     */
    V visit(ExposedBinding<? extends T> binding);


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       Fri May 15 00:10:43 2009
@@ -42,6 +42,7 @@
  import com.google.inject.internal.ProviderMethodsModule;
  import com.google.inject.internal.Sets;
  import com.google.inject.internal.SourceProvider;
+import com.google.inject.internal.ExposureBuilder;
  import com.google.inject.matcher.Matcher;
  import java.lang.annotation.Annotation;
  import java.lang.reflect.Method;
@@ -52,8 +53,8 @@
  import java.util.Set;

  /**
- * Exposes elements of a module so they can be inspected, validated or  
{...@link ModuleWriter
- * rewritten}.
+ * Exposes elements of a module so they can be inspected, validated or  
{...@link
+ * Element#applyTo(Binder) rewritten}.
   *
   * @author [email protected] (Jesse Wilson)
   * @since 2.0
@@ -102,6 +103,19 @@
      return Collections.unmodifiableList(binder.elements);
    }

+  /**
+   * Returns the module composed of {...@code elements}.
+   */
+  public static Module getModule(final Iterable<? extends Element>  
elements) {
+    return new Module() {
+      public void configure(Binder binder) {
+        for (Element element : elements) {
+          element.applyTo(binder);
+        }
+      }
+    };
+  }
+
    @SuppressWarnings("unchecked")
    static <T> BindingTargetVisitor<T, T> getInstanceVisitor() {
      return (BindingTargetVisitor<T, T>) GET_INSTANCE_VISITOR;
@@ -309,10 +323,7 @@
          };
        }

-      BindingBuilder<T> exposeBinding = new BindingBuilder<T>(
-          this, parent.elements, getSource(), key);
-
-      BindingBuilder.ExposureBuilder<T> builder =  
exposeBinding.usingKeyFrom(privateElements);
+      ExposureBuilder<T> builder = new ExposureBuilder<T>(this,  
getSource(), key);
        privateElements.addExposureBuilder(builder);
        return builder;
      }

Modified: trunk/src/com/google/inject/spi/PrivateElements.java
==============================================================================
--- trunk/src/com/google/inject/spi/PrivateElements.java        (original)
+++ trunk/src/com/google/inject/spi/PrivateElements.java        Fri May 15  
00:10:43 2009
@@ -45,4 +45,16 @@
     * Returns the unique exposed keys for these private elements.
     */
    Set<Key<?>> getExposedKeys();
+
+  /**
+   * Returns an arbitrary object containing information about the "place"  
where this key was
+   * exposed. Used by Guice in the production of descriptive error  
messages.
+   *
+   * <p>Tools might specially handle types they know about; {...@code  
StackTraceElement} is a good
+   * example. Tools should simply call {...@code toString()} on the source  
object if the type is
+   * unfamiliar.
+   *
+   * @param key one of the keys exposed by this module.
+   */
+  Object getExposedSource(Key<?> key);
  }

Modified: trunk/src/com/google/inject/util/Modules.java
==============================================================================
--- trunk/src/com/google/inject/util/Modules.java       (original)
+++ trunk/src/com/google/inject/util/Modules.java       Fri May 15 00:10:43 2009
@@ -22,15 +22,17 @@
  import com.google.inject.Key;
  import com.google.inject.Module;
  import com.google.inject.Scope;
+import com.google.inject.PrivateBinder;
  import com.google.inject.internal.ImmutableSet;
  import com.google.inject.internal.Lists;
  import com.google.inject.internal.Maps;
  import com.google.inject.internal.Sets;
  import com.google.inject.spi.DefaultBindingScopingVisitor;
+import com.google.inject.spi.DefaultElementVisitor;
  import com.google.inject.spi.Element;
  import com.google.inject.spi.Elements;
-import com.google.inject.spi.ModuleWriter;
  import com.google.inject.spi.ScopeBinding;
+import com.google.inject.spi.PrivateElements;
  import java.lang.annotation.Annotation;
  import java.util.Arrays;
  import java.util.List;
@@ -144,27 +146,32 @@
            final Set<Class<? extends Annotation>> overridesScopeAnnotations  
= Sets.newHashSet();

            // execute the overrides module, keeping track of which keys and  
scopes are bound
-          new ModuleWriter() {
-            @Override public <T> void writeBind(Binder binder, Binding<T>  
binding) {
+          new ModuleWriter(binder()) {
+            @Override public <T> Void visit(Binding<T> binding) {
                overriddenKeys.add(binding.getKey());
-              super.writeBind(binder, binding);
+              return super.visit(binding);
              }

-            @Override public void writeBindScope(Binder binder,  
ScopeBinding element) {
-              overridesScopeAnnotations.add(element.getAnnotationType());
-              super.writeBindScope(binder, element);
+            @Override public Void visit(ScopeBinding scopeBinding) {
+               
overridesScopeAnnotations.add(scopeBinding.getAnnotationType());
+              return super.visit(scopeBinding);
              }
-          }.apply(binder(), overrideElements);
+
+            @Override public Void visit(PrivateElements privateElements) {
+              overriddenKeys.addAll(privateElements.getExposedKeys());
+              return super.visit(privateElements);
+            }
+          }.writeAll(overrideElements);

            // execute the original module, skipping all scopes and  
overridden keys. We only skip each
            // overridden binding once so things still blow up if the module  
binds the same thing
            // multiple times.
            final Map<Scope, Object> scopeInstancesInUse = Maps.newHashMap();
            final List<ScopeBinding> scopeBindings = Lists.newArrayList();
-          new ModuleWriter() {
-            @Override public <T> void writeBind(Binder binder, final  
Binding<T> binding) {
+          new ModuleWriter(binder()) {
+            @Override public <T> Void visit(Binding<T> binding) {
                if (!overriddenKeys.remove(binding.getKey())) {
-                super.writeBind(binder, binding);
+                super.visit(binding);

                  // Record when a scope instance is used in a binding
                  Scope scope = getScopeInstanceOrNull(binding);
@@ -172,29 +179,60 @@
                    scopeInstancesInUse.put(scope, binding.getSource());
                  }
                }
+
+              return null;
+            }
+
+            @Override public Void visit(PrivateElements privateElements) {
+              PrivateBinder privateBinder =  
binder.withSource(privateElements.getSource())
+                  .newPrivateBinder();
+
+              Set<Key<?>> skippedExposes = Sets.newHashSet();
+
+              for (Key<?> key : privateElements.getExposedKeys()) {
+                if (overriddenKeys.remove(key)) {
+                  skippedExposes.add(key);
+                } else {
+                   
privateBinder.withSource(privateElements.getExposedSource(key)).expose(key);
+                }
+              }
+
+              // we're not skipping deep exposes, but that should be okay.  
If we ever need to, we
+              // have to search through this set of elements for  
PrivateElements, recursively
+              for (Element element : privateElements.getElements()) {
+                if (element instanceof Binding
+                    && skippedExposes.contains(((Binding)  
element).getKey())) {
+                  continue;
+                }
+                element.applyTo(privateBinder);
+              }
+
+              return null;
              }

-            @Override public void writeBindScope(Binder binder,  
ScopeBinding element) {
-              scopeBindings.add(element);
+            @Override public Void visit(ScopeBinding scopeBinding) {
+              scopeBindings.add(scopeBinding);
+              return null;
              }
-          }.apply(binder(), elements);
+          }.writeAll(elements);

            // execute the scope bindings, skipping scopes that have been  
overridden. Any scope that
            // is overridden and in active use will prompt an error
-          new ModuleWriter() {
-            @Override public void writeBindScope(Binder binder,  
ScopeBinding element) {
-              if  
(!overridesScopeAnnotations.remove(element.getAnnotationType())) {
-                super.writeBindScope(binder, element);
+          new ModuleWriter(binder()) {
+            @Override public Void visit(ScopeBinding scopeBinding) {
+              if  
(!overridesScopeAnnotations.remove(scopeBinding.getAnnotationType())) {
+                super.visit(scopeBinding);
                } else {
-                Object source =  
scopeInstancesInUse.get(element.getScope());
+                Object source =  
scopeInstancesInUse.get(scopeBinding.getScope());
                  if (source != null) {
                    binder().withSource(source).addError(
                        "The scope for @%s is bound directly and cannot be  
overridden.",
-                      element.getAnnotationType().getSimpleName());
+                      scopeBinding.getAnnotationType().getSimpleName());
                  }
                }
+              return null;
              }
-          }.apply(binder(), scopeBindings);
+          }.writeAll(scopeBindings);

            // TODO: bind the overridden keys using multibinder
          }
@@ -207,6 +245,25 @@
            });
          }
        };
+    }
+  }
+
+  private static class ModuleWriter extends DefaultElementVisitor<Void> {
+    protected final Binder binder;
+
+    ModuleWriter(Binder binder) {
+      this.binder = binder;
+    }
+
+    @Override protected Void visitOther(Element element) {
+      element.applyTo(binder);
+      return null;
+    }
+
+    void writeAll(Iterable<? extends Element> elements) {
+      for (Element element : elements) {
+        element.acceptVisitor(this);
+      }
      }
    }
  }

Modified: trunk/test/com/google/inject/AllTests.java
==============================================================================
--- trunk/test/com/google/inject/AllTests.java  (original)
+++ trunk/test/com/google/inject/AllTests.java  Fri May 15 00:10:43 2009
@@ -23,16 +23,17 @@
  import com.google.inject.internal.UniqueAnnotationsTest;
  import com.google.inject.matcher.MatcherTest;
  import com.google.inject.name.NamesTest;
+import com.google.inject.spi.BindingTargetVisitorTest;
  import com.google.inject.spi.ElementsTest;
  import com.google.inject.spi.HasDependenciesTest;
  import com.google.inject.spi.InjectionPointTest;
  import com.google.inject.spi.ModuleRewriterTest;
-import com.google.inject.spi.ModuleWriterTest;
  import com.google.inject.spi.ProviderMethodsTest;
  import com.google.inject.spi.SpiBindingsTest;
-import com.google.inject.spi.BindingTargetVisitorTest;
+import com.google.inject.spi.ElementApplyToTest;
  import com.google.inject.util.ProvidersTest;
  import com.google.inject.util.TypesTest;
+import com.google.inject.util.NoopOverrideTest;
  import junit.framework.Test;
  import junit.framework.TestSuite;

@@ -99,10 +100,10 @@
      // spi
      suite.addTestSuite(BindingTargetVisitorTest.class);
      suite.addTestSuite(ElementsTest.class);
+    suite.addTestSuite(ElementApplyToTest.class);
      suite.addTestSuite(HasDependenciesTest.class);
      suite.addTestSuite(InjectionPointTest.class);
      suite.addTestSuite(ModuleRewriterTest.class);
-    suite.addTestSuite(ModuleWriterTest.class);
      suite.addTestSuite(ProviderMethodsTest.class);
      suite.addTestSuite(SpiBindingsTest.class);

@@ -110,6 +111,7 @@
      // suite.addTestSuite(JmxTest.class); not a testcase

      // util
+    suite.addTestSuite(NoopOverrideTest.class);
      suite.addTestSuite(ProvidersTest.class);
      suite.addTestSuite(TypesTest.class);


Modified: trunk/test/com/google/inject/OverrideModuleTest.java
==============================================================================
--- trunk/test/com/google/inject/OverrideModuleTest.java        (original)
+++ trunk/test/com/google/inject/OverrideModuleTest.java        Fri May 15  
00:10:43 2009
@@ -201,6 +201,21 @@
      }
    }

+  public void testStandardScopeAnnotation() {
+    final SingleUseScope scope = new SingleUseScope();
+
+    Module module = new AbstractModule() {
+      protected void configure() {
+        bindScope(TestScopeAnnotation.class, scope);
+        bind(String.class).in(TestScopeAnnotation.class);
+      }
+    };
+    assertFalse(scope.used);
+
+    Guice.createInjector(module);
+    assertTrue(scope.used);
+  }
+
    public void testOverrideUntargettedBinding() {
      Module original = new AbstractModule() {
        @Override protected void configure() {
@@ -296,6 +311,80 @@
      Injector injector = Guice.createInjector(overridden);
      assertEquals("B", injector.getInstance(Key.get(String.class,  
named("original"))));
      assertEquals("B", injector.getInstance(Key.get(String.class,  
named("override"))));
+  }
+
+  public void testOverridePrivateModuleOverPrivateModule() {
+    Module exposes5and6 = new AbstractModule() {
+      protected void configure() {
+        install(new PrivateModule() {
+          protected void configure() {
+            bind(Integer.class).toInstance(5);
+            expose(Integer.class);
+
+            bind(Character.class).toInstance('E');
+          }
+        });
+
+        install(new PrivateModule() {
+          protected void configure() {
+            bind(Long.class).toInstance(6L);
+            expose(Long.class);
+
+            bind(Character.class).toInstance('F');
+          }
+        });
+      }
+    };
+
+    AbstractModule exposes15 = new AbstractModule() {
+      protected void configure() {
+        install(new PrivateModule() {
+          protected void configure() {
+            bind(Integer.class).toInstance(15);
+            expose(Integer.class);
+
+            bind(Character.class).toInstance('G');
+          }
+        });
+
+        install(new PrivateModule() {
+          protected void configure() {
+            bind(Character.class).toInstance('H');
+          }
+        });
+      }
+    };
+
+    // override forwards
+    Injector injector =  
Guice.createInjector(Modules.override(exposes5and6).with(exposes15));
+    assertEquals(15, injector.getInstance(Integer.class).intValue());
+    assertEquals(6L, injector.getInstance(Long.class).longValue());
+
+    // and in reverse order
+    Injector reverse =  
Guice.createInjector(Modules.override(exposes15).with(exposes5and6));
+    assertEquals(5, reverse.getInstance(Integer.class).intValue());
+    assertEquals(6L, reverse.getInstance(Long.class).longValue());
+  }
+
+  public void testOverrideModuleAndPrivateModule() {
+    Module exposes5 = new PrivateModule() {
+      protected void configure() {
+        bind(Integer.class).toInstance(5);
+        expose(Integer.class);
+      }
+    };
+
+    Module binds15 = new AbstractModule() {
+      protected void configure() {
+        bind(Integer.class).toInstance(15);
+      }
+    };
+
+    Injector injector =  
Guice.createInjector(Modules.override(exposes5).with(binds15));
+    assertEquals(15, injector.getInstance(Integer.class).intValue());
+
+    Injector reverse =  
Guice.createInjector(Modules.override(binds15).with(exposes5));
+    assertEquals(5, reverse.getInstance(Integer.class).intValue());
    }

    @Retention(RUNTIME)

Modified: trunk/test/com/google/inject/PrivateModuleTest.java
==============================================================================
--- trunk/test/com/google/inject/PrivateModuleTest.java (original)
+++ trunk/test/com/google/inject/PrivateModuleTest.java Fri May 15 00:10:43  
2009
@@ -441,6 +441,8 @@
      PrivateElements privateElements = binding.getPrivateElements();
      assertEquals(ImmutableSet.<Key<?>>of(Key.get(String.class,  
named("b"))),
          privateElements.getExposedKeys());
+    assertContains(privateElements.getExposedSource(Key.get(String.class,  
named("b"))).toString(),
+         
PrivateModuleTest.class.getName(), ".configure(PrivateModuleTest.java:");
      Injector privateInjector = privateElements.getInjector();
      assertEquals("private",  
privateInjector.getInstance(Key.get(String.class, Names.named("a"))));
    }

Modified: trunk/test/com/google/inject/spi/ElementApplyToTest.java
==============================================================================
--- trunk/test/com/google/inject/spi/ElementApplyToTest.java    (original)
+++ trunk/test/com/google/inject/spi/ElementApplyToTest.java    Fri May 15  
00:10:43 2009
@@ -16,9 +16,7 @@

  package com.google.inject.spi;

-import com.google.inject.AbstractModule;
  import com.google.inject.Module;
-import java.util.List;

  /**
   * @author [email protected] (Jesse Wilson)
@@ -26,24 +24,7 @@
  public class ElementApplyToTest extends ElementsTest {

    protected void checkModule(Module module, ElementVisitor<?>... visitors)  
{
-    // get some elements to apply
-    final List<Element> elements = Elements.getElements(module);
-
-    // apply the elements, and extract them again!
-    List<Element> rewrittenElements = Elements.getElements(new  
AbstractModule() {
-      protected void configure() {
-        for (Element element : elements) {
-          element.applyTo(binder());
-        }
-      }
-    });
-
-    // verify that the replayed elements are as expected
-    assertEquals(rewrittenElements.size(), visitors.length);
-    for (int i = 0; i < visitors.length; i++) {
-      ElementVisitor<?> visitor = visitors[i];
-      Element element = rewrittenElements.get(i);
-      element.acceptVisitor(visitor);
-    }
+    // convert from module to elements and back
+    super.checkModule(Elements.getModule(Elements.getElements(module)),  
visitors);
    }
  }

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  Fri May 15 00:10:43  
2009
@@ -854,34 +854,6 @@
          },

          new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> binding) {
-            assertTrue(binding instanceof ExposedBinding);
-            assertEquals(arrayList, binding.getKey());
-            binding.acceptTargetVisitor(new FailingTargetVisitor<T>() {
-              @Override public Void visit(ExposedBinding<? extends T>  
binding) {
-                assertEquals(collections,  
binding.getPrivateElements().getExposedKeys());
-                return null;
-              }
-            });
-            return null;
-          }
-        },
-
-        new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> binding) {
-            assertTrue(binding instanceof ExposedBinding);
-            assertEquals(collection, binding.getKey());
-            binding.acceptTargetVisitor(new FailingTargetVisitor<T>() {
-              @Override public Void visit(ExposedBinding<? extends T>  
binding) {
-                assertEquals(collections,  
binding.getPrivateElements().getExposedKeys());
-                return null;
-              }
-            });
-            return null;
-          }
-        },
-
-        new FailingElementVisitor() {
            @Override public Void visit(PrivateElements two) {
              assertEquals(ab, two.getExposedKeys());
              assertEquals("1 ElementsTest.java", two.getSource());
@@ -894,36 +866,6 @@
                    }
                  }
              );
-            return null;
-          }
-        },
-
-        new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> binding) {
-            assertTrue(binding instanceof ExposedBinding);
-            assertEquals(a, binding.getKey());
-            assertEquals("2 ElementsTest.java", binding.getSource());
-            binding.acceptTargetVisitor(new FailingTargetVisitor<T>() {
-              @Override public Void visit(ExposedBinding<? extends T>  
binding) {
-                assertEquals(ab,  
binding.getPrivateElements().getExposedKeys());
-                return null;
-              }
-            });
-            return null;
-          }
-        },
-
-        new FailingElementVisitor() {
-          @Override public <T> Void visit(Binding<T> binding) {
-            assertTrue(binding instanceof ExposedBinding);
-            assertEquals(b, binding.getKey());
-            assertEquals("2 ElementsTest.java", binding.getSource());
-            binding.acceptTargetVisitor(new FailingTargetVisitor<T>() {
-              @Override public Void visit(ExposedBinding<? extends T>  
binding) {
-                assertEquals(ab,  
binding.getPrivateElements().getExposedKeys());
-                return null;
-              }
-            });
              return null;
            }
          }

Modified: trunk/test/com/google/inject/spi/ModuleRewriterTest.java
==============================================================================
--- trunk/test/com/google/inject/spi/ModuleRewriterTest.java    (original)
+++ trunk/test/com/google/inject/spi/ModuleRewriterTest.java    Fri May 15  
00:10:43 2009
@@ -17,14 +17,15 @@
  package com.google.inject.spi;

  import com.google.inject.AbstractModule;
-import com.google.inject.Binder;
  import com.google.inject.Binding;
+import com.google.inject.ConfigurationException;
  import com.google.inject.Guice;
  import com.google.inject.Inject;
  import com.google.inject.Injector;
  import com.google.inject.Key;
  import com.google.inject.Module;
  import com.google.inject.Provider;
+import com.google.inject.internal.Lists;
  import com.google.inject.name.Names;
  import java.util.List;
  import junit.framework.TestCase;
@@ -48,24 +49,34 @@
      List<Element> elements = Elements.getElements(module);

      // create a rewriter that rewrites the binding to 'Wine' with a  
binding to 'Beer'
-    ModuleWriter rewriter = new ModuleWriter() {
-      @Override public <T> void writeBind(Binder binder, Binding<T>  
binding) {
-        T target =  
binding.acceptTargetVisitor(Elements.<T>getInstanceVisitor());
-        if ("Wine".equals(target)) {
-          binder.bind(CharSequence.class).toInstance("Beer");
-        } else {
-          super.writeBind(binder, binding);
+    List<Element> rewritten = Lists.newArrayList();
+    for (Element element : elements) {
+      element = element.acceptVisitor(new DefaultElementVisitor<Element>()  
{
+        @Override public <T> Element visit(Binding<T> binding) {
+          T target =  
binding.acceptTargetVisitor(Elements.<T>getInstanceVisitor());
+          if ("Wine".equals(target)) {
+            return null;
+          }
+          else {
+            return binding;
+          }
          }
+      });
+      if (element != null) {
+        rewritten.add(element);
        }
-    };
+    }

      // create a module from the original list of elements and the rewriter
-    Module rewrittenModule = rewriter.create(elements);
+    Module rewrittenModule = Elements.getModule(rewritten);

-    // it all works
+    // the wine binding is dropped
      Injector injector = Guice.createInjector(rewrittenModule);
-    assertEquals("Pizza", injector.getInstance(String.class));
-    assertEquals("Beer", injector.getInstance(CharSequence.class));
+    try {
+      injector.getInstance(CharSequence.class);
+      fail();
+    } catch (ConfigurationException expected) {
+    }
    }

    public void testGetProviderAvailableAtInjectMembersTime() {
@@ -95,7 +106,7 @@

      // and it should also work fine if we rewrite it
      List<Element> elements = Elements.getElements(module);
-    Module replayed = new ModuleWriter().create(elements);
+    Module replayed = Elements.getModule(elements);
      Injector replayedInjector = Guice.createInjector(replayed);
      assertEquals("A", replayedInjector.getInstance(Key.get(String.class,  
Names.named("2"))));
    }

Copied: trunk/test/com/google/inject/util/NoopOverrideTest.java (from r936,  
/trunk/test/com/google/inject/spi/ElementApplyToTest.java)
==============================================================================
--- /trunk/test/com/google/inject/spi/ElementApplyToTest.java   (original)
+++ trunk/test/com/google/inject/util/NoopOverrideTest.java     Fri May 15  
00:10:43 2009
@@ -14,36 +14,19 @@
   * limitations under the License.
   */

-package com.google.inject.spi;
+package com.google.inject.util;

-import com.google.inject.AbstractModule;
  import com.google.inject.Module;
-import java.util.List;
+import com.google.inject.spi.ElementVisitor;
+import com.google.inject.spi.ElementsTest;

  /**
   * @author [email protected] (Jesse Wilson)
   */
-public class ElementApplyToTest extends ElementsTest {
+public class NoopOverrideTest extends ElementsTest {

    protected void checkModule(Module module, ElementVisitor<?>... visitors)  
{
-    // get some elements to apply
-    final List<Element> elements = Elements.getElements(module);
-
-    // apply the elements, and extract them again!
-    List<Element> rewrittenElements = Elements.getElements(new  
AbstractModule() {
-      protected void configure() {
-        for (Element element : elements) {
-          element.applyTo(binder());
-        }
-      }
-    });
-
-    // verify that the replayed elements are as expected
-    assertEquals(rewrittenElements.size(), visitors.length);
-    for (int i = 0; i < visitors.length; i++) {
-      ElementVisitor<?> visitor = visitors[i];
-      Element element = rewrittenElements.get(i);
-      element.acceptVisitor(visitor);
-    }
+    Module overridden =  
Modules.override(module).with(Modules.EMPTY_MODULE);
+    super.checkModule(overridden, visitors);
    }
  }

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