4 new revisions:

Revision: e5ed5b4fee89
Author:   Christian Edward Gruber <cgru...@google.com>
Date:     Wed May 15 16:45:21 2013
Log: Add an @Inject constructor to DefaultFilterPipeline so services which ...
http://code.google.com/p/google-guice/source/detail?r=e5ed5b4fee89

Revision: 23030077f4b7
Author:   Christian Edward Gruber <cgru...@google.com>
Date:     Wed May 15 17:32:52 2013
Log:      Upgrade to cglib 3.0 adn ASM 4.0....
http://code.google.com/p/google-guice/source/detail?r=23030077f4b7

Revision: a1867f8bcfac
Author:   Christian Edward Gruber <cgru...@google.com>
Date:     Wed May 15 17:52:45 2013
Log:      update cglib dependency in poms.
http://code.google.com/p/google-guice/source/detail?r=a1867f8bcfac

Revision: bf2b16c06a5f
Author:   Christian Edward Gruber <cgru...@google.com>
Date:     Wed May 15 18:39:15 2013
Log: Add support for ProvisionListeners to notify on toInstance & constant ...
http://code.google.com/p/google-guice/source/detail?r=bf2b16c06a5f

==============================================================================
Revision: e5ed5b4fee89
Author:   Christian Edward Gruber <cgru...@google.com>
Date:     Wed May 15 16:45:21 2013
Log: Add an @Inject constructor to DefaultFilterPipeline so services which depend upon it can be used with Modules.requireAtInjectOnConstructorsModule()

----------------
Manually synced.
COMMIT=33399588

http://code.google.com/p/google-guice/source/detail?r=e5ed5b4fee89

Modified:
/extensions/servlet/src/com/google/inject/servlet/DefaultFilterPipeline.java

=======================================
--- /extensions/servlet/src/com/google/inject/servlet/DefaultFilterPipeline.java Sun Oct 16 15:35:11 2011 +++ /extensions/servlet/src/com/google/inject/servlet/DefaultFilterPipeline.java Wed May 15 16:45:21 2013
@@ -17,6 +17,7 @@

 import java.io.IOException;

+import javax.inject.Inject;
 import javax.servlet.FilterChain;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
@@ -30,6 +31,9 @@
* @see com.google.inject.servlet.ManagedFilterPipeline See Also ManagedFilterPipeline.
  */
 class DefaultFilterPipeline implements FilterPipeline {
+  @Inject DefaultFilterPipeline() {
+  }
+
   public void initPipeline(ServletContext context) {
   }


==============================================================================
Revision: 23030077f4b7
Author:   Christian Edward Gruber <cgru...@google.com>
Date:     Wed May 15 17:32:52 2013
Log:      Upgrade to cglib 3.0 adn ASM 4.0.

------------------
Manually synced.
COMMIT=35272017

http://code.google.com/p/google-guice/source/detail?r=23030077f4b7

Added:
 /extensions/persist/lib/cglib-nodep-3.0.jar
 /lib/build/asm-4.0.jar
 /lib/build/asm-util-4.0.jar
 /lib/build/cglib-3.0.jar
Deleted:
 /extensions/persist/lib/cglib-nodep-2.2.jar
 /lib/build/asm-3.3.1.jar
 /lib/build/cglib-2.2.2.jar
Modified:
 /build.xml
 /common.xml
 /core/src/com/google/inject/internal/util/LineNumbers.java

=======================================
--- /dev/null   
+++ /extensions/persist/lib/cglib-nodep-3.0.jar Wed May 15 17:32:52 2013
Binary file, no diff available.
=======================================
--- /dev/null   
+++ /lib/build/asm-4.0.jar      Wed May 15 17:32:52 2013
Binary file, no diff available.
=======================================
--- /dev/null   
+++ /lib/build/asm-util-4.0.jar Wed May 15 17:32:52 2013
Binary file, no diff available.
=======================================
--- /dev/null   
+++ /lib/build/cglib-3.0.jar    Wed May 15 17:32:52 2013
Binary file, no diff available.
=======================================
--- /extensions/persist/lib/cglib-nodep-2.2.jar Fri Sep 10 19:10:20 2010
+++ /dev/null   
Binary file, no diff available.
=======================================
--- /lib/build/asm-3.3.1.jar    Wed Apr 20 09:57:24 2011
+++ /dev/null   
Binary file, no diff available.
=======================================
--- /lib/build/cglib-2.2.2.jar  Wed Apr 20 09:57:24 2011
+++ /dev/null   
Binary file, no diff available.
=======================================
--- /build.xml  Thu Jul  7 17:34:16 2011
+++ /build.xml  Wed May 15 17:32:52 2013
@@ -236,13 +236,16 @@
       <arg value="-DNO_AOP" />
     </munge>
     <replace file="build/no_aop/common.xml" value="">
- <replacetoken><![CDATA[<zipfileset src="${common.basedir}/lib/build/asm-3.3.1.jar"/>]]></replacetoken> + <replacetoken><![CDATA[<zipfileset src="${common.basedir}/lib/build/asm-4.0.jar"/>]]></replacetoken>
     </replace>
     <replace file="build/no_aop/common.xml" value="">
- <replacetoken><![CDATA[<zipfileset src="${common.basedir}/lib/build/cglib-2.2.2.jar"/>]]></replacetoken> + <replacetoken><![CDATA[<zipfileset src="${common.basedir}/lib/build/asm-util-4.0.jar"/>]]></replacetoken>
+    </replace>
+    <replace file="build/no_aop/common.xml" value="">
+ <replacetoken><![CDATA[<zipfileset src="${common.basedir}/lib/build/cglib-3.0.jar"/>]]></replacetoken>
     </replace>
     <replace file="build/no_aop/common.xml" value="">
- <replacetoken><![CDATA[<zipfileset src="${common.basedir}/lib/build/cglib-2.2.2.jar"> + <replacetoken><![CDATA[<zipfileset src="${common.basedir}/lib/build/cglib-3.0.jar">
         <include name="LICENSE"/>
         <include name="NOTICE"/>
       </zipfileset>]]></replacetoken>
=======================================
--- /common.xml Fri Jan 13 15:32:04 2012
+++ /common.xml Wed May 15 17:32:52 2013
@@ -148,8 +148,9 @@
         classpath="${common.basedir}/lib/build/jarjar-1.1.jar"/>
     <jarjar jarfile="${build.dir}/${ant.project.name}-with-deps.jar">
       <fileset dir="${build.dir}/classes"/>
-      <zipfileset src="${common.basedir}/lib/build/cglib-2.2.2.jar"/>
-      <zipfileset src="${common.basedir}/lib/build/asm-3.3.1.jar"/>
+      <zipfileset src="${common.basedir}/lib/build/cglib-3.0.jar"/>
+      <zipfileset src="${common.basedir}/lib/build/asm-4.0.jar"/>
+      <zipfileset src="${common.basedir}/lib/build/asm-util-4.0.jar"/>
       <zipfileset src="${common.basedir}/lib/build/guava-11.0.1.jar"/>
<rule pattern="net.sf.cglib.*" result="com.google.inject.internal.cglib.$@1"/> <rule pattern="net.sf.cglib.**.*" result="com.google.inject.internal.cglib.@1.$@2"/>
@@ -171,7 +172,7 @@
     <taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask"
         classpath="${common.basedir}/lib/build/jarjar-1.1.jar"/>
     <jarjar jarfile="${build.dir}/${ant.project.name}-with-deps.jar">
-      <zipfileset src="${common.basedir}/lib/build/cglib-2.2.2.jar">
+      <zipfileset src="${common.basedir}/lib/build/cglib-3.0.jar">
         <include name="LICENSE"/>
         <include name="NOTICE"/>
       </zipfileset>
=======================================
--- /core/src/com/google/inject/internal/util/LineNumbers.java Thu Jul 7 17:34:16 2011 +++ /core/src/com/google/inject/internal/util/LineNumbers.java Wed May 15 17:32:52 2013
@@ -22,7 +22,6 @@
 import com.google.common.collect.Maps;

 import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.Attribute;
 import org.objectweb.asm.ClassReader;
 import org.objectweb.asm.ClassVisitor;
 import org.objectweb.asm.FieldVisitor;
@@ -123,12 +122,16 @@
     end[NO_AOP]*/
   }

- private class LineNumberReader implements ClassVisitor, MethodVisitor, AnnotationVisitor {
+  private class LineNumberReader extends ClassVisitor {

     private int line = -1;
     private String pendingMethod;
     private String name;

+    LineNumberReader() {
+      super(Opcodes.ASM4);
+    }
+
public void visit(int version, int access, String name, String signature,
         String superName, String[] interfaces) {
       this.name = name;
@@ -141,7 +144,7 @@
       }
       pendingMethod = name + desc;
       line = -1;
-      return this;
+      return new LineNumberMethodVisitor();
     }

     public void visitSource(String source, String debug) {
@@ -159,27 +162,6 @@
         pendingMethod = null;
       }
     }
-
-    public void visitFieldInsn(int opcode, String owner, String name,
-        String desc) {
-      if (opcode == Opcodes.PUTFIELD && this.name.equals(owner)
-          && !lines.containsKey(name) && line != -1) {
-        lines.put(name, line);
-      }
-    }
-
-    public void visitEnd() {
-    }
-
- public void visitInnerClass(String name, String outerName, String innerName,
-        int access) {
-    }
-
-    public void visitOuterClass(String owner, String name, String desc) {
-    }
-
-    public void visitAttribute(Attribute attr) {
-    }

     public FieldVisitor visitField(int access, String name, String desc,
         String signature, Object value) {
@@ -187,86 +169,55 @@
     }

public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-      return this;
-    }
-
-    public AnnotationVisitor visitAnnotation(String name, String desc) {
-      return this;
-    }
-
-    public AnnotationVisitor visitAnnotationDefault() {
-      return this;
+      return new LineNumberAnnotationVisitor();
     }

     public AnnotationVisitor visitParameterAnnotation(int parameter,
         String desc, boolean visible) {
-      return this;
+      return new LineNumberAnnotationVisitor();
     }

-    public AnnotationVisitor visitArray(String name) {
-      return this;
+    class LineNumberMethodVisitor extends MethodVisitor {
+      LineNumberMethodVisitor() {
+        super(Opcodes.ASM4);
     }

-    public void visitEnum(String name, String desc, String value) {
+ public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+        return new LineNumberAnnotationVisitor();
     }

-    public void visit(String name, Object value) {
+      public AnnotationVisitor visitAnnotationDefault() {
+        return new LineNumberAnnotationVisitor();
     }

-    public void visitCode() {
-    }
-
- public void visitFrame(int type, int nLocal, Object[] local, int nStack,
-        Object[] stack) {
+      public void visitFieldInsn(int opcode, String owner, String name,
+          String desc) {
+ if (opcode == Opcodes.PUTFIELD && LineNumberReader.this.name.equals(owner)
+            && !lines.containsKey(name) && line != -1) {
+          lines.put(name, line);
     }
-
-    public void visitIincInsn(int var, int increment) {
     }

-    public void visitInsn(int opcode) {
+      public void visitLineNumber(int line, Label start) {
+        LineNumberReader.this.visitLineNumber(line, start);
     }
-
-    public void visitIntInsn(int opcode, int operand) {
     }

-    public void visitJumpInsn(int opcode, Label label) {
+    class LineNumberAnnotationVisitor extends AnnotationVisitor {
+      LineNumberAnnotationVisitor() {
+        super(Opcodes.ASM4);
     }
-
-    public void visitLabel(Label label) {
+      public AnnotationVisitor visitAnnotation(String name, String desc) {
+        return this;
     }
-
-    public void visitLdcInsn(Object cst) {
+      public AnnotationVisitor visitArray(String name) {
+        return this;
     }
-
public void visitLocalVariable(String name, String desc, String signature,
         Label start, Label end, int index) {
     }

- public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
-    }
-
-    public void visitMaxs(int maxStack, int maxLocals) {
-    }
-
-    public void visitMethodInsn(int opcode, String owner, String name,
-        String desc) {
-    }
-
-    public void visitMultiANewArrayInsn(String desc, int dims) {
-    }
-
-    public void visitTableSwitchInsn(int min, int max, Label dflt,
-        Label[] labels) {
-    }
-
-    public void visitTryCatchBlock(Label start, Label end, Label handler,
-        String type) {
-    }
-
-    public void visitTypeInsn(int opcode, String desc) {
     }

-    public void visitVarInsn(int opcode, int var) {
-    }
   }
 }

==============================================================================
Revision: a1867f8bcfac
Author:   Christian Edward Gruber <cgru...@google.com>
Date:     Wed May 15 17:52:45 2013
Log:      update cglib dependency in poms.

http://code.google.com/p/google-guice/source/detail?r=a1867f8bcfac

Modified:
 /core/pom.xml

=======================================
--- /core/pom.xml       Fri Aug 31 02:41:33 2012
+++ /core/pom.xml       Wed May 15 17:52:45 2013
@@ -14,7 +14,7 @@
   <name>Google Guice - Core Library</name>

   <properties>
-    <cglib.version>2.2.2</cglib.version>
+    <cglib.version>3.0</cglib.version>
   </properties>

   <dependencies>

==============================================================================
Revision: bf2b16c06a5f
Author:   Christian Edward Gruber <cgru...@google.com>
Date:     Wed May 15 18:39:15 2013
Log: Add support for ProvisionListeners to notify on toInstance & constant bindings.

---------------------
Manually synced.
COMMIT=41634417

http://code.google.com/p/google-guice/source/detail?r=bf2b16c06a5f

Modified:
 /core/src/com/google/inject/internal/AbstractBindingProcessor.java
 /core/src/com/google/inject/internal/BindingProcessor.java
 /core/src/com/google/inject/internal/Initializer.java
 /core/src/com/google/inject/internal/InjectorShell.java
 /core/src/com/google/inject/internal/MembersInjectorImpl.java
 /core/src/com/google/inject/internal/ProvisionListenerCallbackStore.java
 /core/src/com/google/inject/internal/ProvisionListenerStackCallback.java
 /core/src/com/google/inject/spi/ProvisionListener.java
 /core/test/com/google/inject/BinderTest.java
 /core/test/com/google/inject/BindingTest.java
 /core/test/com/google/inject/ProvisionListenerTest.java
 /core/test/com/google/inject/TypeListenerTest.java
/extensions/multibindings/test/com/google/inject/multibindings/SpiUtils.java

=======================================
--- /core/src/com/google/inject/internal/AbstractBindingProcessor.java Thu Jul 7 17:34:16 2011 +++ /core/src/com/google/inject/internal/AbstractBindingProcessor.java Wed May 15 18:39:15 2013
@@ -26,6 +26,7 @@
 import com.google.inject.Module;
 import com.google.inject.Provider;
 import com.google.inject.Scope;
+import com.google.inject.Stage;
 import com.google.inject.TypeLiteral;
 import com.google.inject.spi.DefaultBindingTargetVisitor;

@@ -51,8 +52,8 @@
       Module.class,
       Provider.class,
       Scope.class,
+      Stage.class,
       TypeLiteral.class);
-  // TODO(jessewilson): fix BuiltInModule, then add Stage

   protected final ProcessedBindingData bindingData;

=======================================
--- /core/src/com/google/inject/internal/BindingProcessor.java Thu May 31 16:54:04 2012 +++ /core/src/com/google/inject/internal/BindingProcessor.java Wed May 15 18:39:15 2013
@@ -87,8 +87,10 @@
         prepareBinding();
         Set<InjectionPoint> injectionPoints = binding.getInjectionPoints();
         T instance = binding.getInstance();
+ @SuppressWarnings("unchecked") // safe to cast to binding<T> because + // the processor was constructed w/ it
         Initializable<T> ref = initializer.requestInjection(
-            injector, instance, key, source, injectionPoints);
+ injector, instance, (Binding<T>) binding, source, injectionPoints);
         ConstantFactory<? extends T> factory = new ConstantFactory<T>(ref);
         InternalFactory<? extends T> scopedFactory
             = Scoping.scope(key, injector, factory, source, scoping);
=======================================
--- /core/src/com/google/inject/internal/Initializer.java Mon Oct 31 13:34:57 2011 +++ /core/src/com/google/inject/internal/Initializer.java Wed May 15 18:39:15 2013
@@ -21,6 +21,7 @@
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
+import com.google.inject.Binding;
 import com.google.inject.Key;
 import com.google.inject.Stage;
 import com.google.inject.TypeLiteral;
@@ -57,21 +58,25 @@
    *
* @param instance an instance that optionally has members to be injected (each annotated with
    *      @Inject).
-   * @param key a key to use for keeping the state of the dependency chain
+ * @param binding the binding that caused this initializable to be created, if it exists.
    * @param source the source location that this injection was requested
    */
- <T> Initializable<T> requestInjection(InjectorImpl injector, T instance, Key<T> key, + <T> Initializable<T> requestInjection(InjectorImpl injector, T instance, Binding<T> binding,
       Object source, Set<InjectionPoint> injectionPoints) {
     checkNotNull(source);

-    // short circuit if the object has no injections
-    if (instance == null
- || (injectionPoints.isEmpty() && !injector.membersInjectorStore.hasTypeListeners())) {
+    ProvisionListenerStackCallback<T> provisionCallback =
+ binding == null ? null : injector.provisionListenerStore.get(binding);
+
+    // short circuit if the object has no injections or listeners.
+    if (instance == null || (injectionPoints.isEmpty()
+        && !injector.membersInjectorStore.hasTypeListeners()
+ && (provisionCallback == null | | !provisionCallback.hasListeners()))) {
       return Initializables.of(instance);
     }

-    InjectableReference<T> initializable =
-        new InjectableReference<T>(injector, instance, key, source);
+    InjectableReference<T> initializable = new InjectableReference<T>(
+ injector, instance, binding == null ? null : binding.getKey(), provisionCallback, source);
     pendingInjection.put(instance, initializable);
     return initializable;
   }
@@ -118,10 +123,13 @@
     private final T instance;
     private final Object source;
     private final Key<T> key;
+    private final ProvisionListenerStackCallback<T> provisionCallback;

- public InjectableReference(InjectorImpl injector, T instance, Key<T> key, Object source) { + public InjectableReference(InjectorImpl injector, T instance, Key<T> key, + ProvisionListenerStackCallback<T> provisionCallback, Object source) {
       this.injector = injector;
       this.key = key; // possibly null!
+      this.provisionCallback = provisionCallback; // possibly null!
       this.instance = checkNotNull(instance, "instance");
       this.source = checkNotNull(source, "source");
     }
@@ -163,7 +171,11 @@

// if in Stage.TOOL, we only want to inject & notify toolable injection points.
         // (otherwise we'll inject all of them)
- membersInjector.injectAndNotify(instance, errors.withSource(source), key, source,
+        membersInjector.injectAndNotify(instance,
+            errors.withSource(source),
+            key,
+            provisionCallback,
+            source,
             injector.options.stage == Stage.TOOL);
       }

=======================================
--- /core/src/com/google/inject/internal/InjectorShell.java Thu Jul 7 17:34:16 2011 +++ /core/src/com/google/inject/internal/InjectorShell.java Wed May 15 18:39:15 2013
@@ -129,9 +129,9 @@
checkState(privateElements == null || parent != null, "PrivateElements with no parent");
       checkState(state != null, "no state. Did you remember to lock() ?");

-      // bind Stage and Singleton if this is a top-level injector
+      // bind Singleton if this is a top-level injector
       if (parent == null) {
-        modules.add(0, new RootModule(stage));
+        modules.add(0, new RootModule());
       }
       elements.addAll(Elements.getElements(stage, modules));

@@ -174,6 +174,7 @@
new TypeConverterBindingProcessor(errors).process(injector, elements);
       stopwatch.resetAndLog("Converters creation");

+      bindStage(injector, stage);
       bindInjector(injector);
       bindLogger(injector);

@@ -270,16 +271,21 @@
     }
   }

-  private static class RootModule implements Module {
-    final Stage stage;
-
-    private RootModule(Stage stage) {
-      this.stage = checkNotNull(stage, "stage");
+  private static void bindStage(InjectorImpl injector, Stage stage) {
+    Key<Stage> key = Key.get(Stage.class);
+ InstanceBindingImpl<Stage> stageBinding = new InstanceBindingImpl<Stage>(
+        injector,
+        key,
+        SourceProvider.UNKNOWN_SOURCE,
+        new ConstantFactory<Stage>(Initializables.of(stage)),
+        ImmutableSet.<InjectionPoint>of(),
+        stage);
+    injector.state.putBinding(key, stageBinding);
     }

+  private static class RootModule implements Module {
     public void configure(Binder binder) {
       binder = binder.withSource(SourceProvider.UNKNOWN_SOURCE);
-      binder.bind(Stage.class).toInstance(stage);
       binder.bindScope(Singleton.class, SINGLETON);
       binder.bindScope(javax.inject.Singleton.class, SINGLETON);
     }
=======================================
--- /core/src/com/google/inject/internal/MembersInjectorImpl.java Thu Jul 7 17:34:16 2011 +++ /core/src/com/google/inject/internal/MembersInjectorImpl.java Wed May 15 18:39:15 2013
@@ -21,6 +21,7 @@
 import com.google.inject.Key;
 import com.google.inject.MembersInjector;
 import com.google.inject.TypeLiteral;
+import com.google.inject.internal.ProvisionListenerStackCallback.ProvisionCallback;
 import com.google.inject.spi.InjectionListener;
 import com.google.inject.spi.InjectionPoint;

@@ -58,7 +59,7 @@
   public void injectMembers(T instance) {
     Errors errors = new Errors(typeLiteral);
     try {
-      injectAndNotify(instance, errors, null, typeLiteral, false);
+      injectAndNotify(instance, errors, null, null, typeLiteral, false);
     } catch (ErrorsException e) {
       errors.merge(e.getErrors());
     }
@@ -66,18 +67,31 @@
     errors.throwProvisionExceptionIfErrorsExist();
   }

-  void injectAndNotify(final T instance, final Errors errors,
-      final Key<T> key, final Object source, final boolean toolableOnly)
-      throws ErrorsException {
+  void injectAndNotify(final T instance,
+      final Errors errors,
+      final Key<T> key, // possibly null!
+ final ProvisionListenerStackCallback<T> provisionCallback, // possibly null!
+      final Object source,
+      final boolean toolableOnly) throws ErrorsException {
     if (instance == null) {
       return;
     }

     injector.callInContext(new ContextualCallable<Void>() {
-      public Void call(InternalContext context) throws ErrorsException {
+      @Override
+ public Void call(final InternalContext context) throws ErrorsException {
         context.pushState(key, source);
         try {
+ if (provisionCallback != null && provisionCallback.hasListeners()) { + provisionCallback.provision(errors, context, new ProvisionCallback<T>() {
+              @Override public T call() {
           injectMembers(instance, errors, context, toolableOnly);
+                return instance;
+              }
+            });
+          } else {
+            injectMembers(instance, errors, context, toolableOnly);
+          }
         } finally {
           context.popState();
         }
=======================================
--- /core/src/com/google/inject/internal/ProvisionListenerCallbackStore.java Sun Feb 26 18:23:19 2012 +++ /core/src/com/google/inject/internal/ProvisionListenerCallbackStore.java Wed May 15 18:39:15 2013
@@ -18,15 +18,20 @@

 import com.google.common.base.Function;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
 import com.google.common.collect.MapMaker;
 import com.google.inject.Binding;
+import com.google.inject.Injector;
 import com.google.inject.Key;
+import com.google.inject.Stage;
 import com.google.inject.spi.ProvisionListener;
 import com.google.inject.spi.ProvisionListenerBinding;

 import java.util.List;
 import java.util.Map;
+import java.util.Set;
+import java.util.logging.Logger;

 /**
  * {@link ProvisionListenerStackCallback} for each key.
@@ -34,6 +39,12 @@
  * @author sa...@google.com (Sam Berlin)
  */
 final class ProvisionListenerCallbackStore {
+
+  // TODO(sameb): Consider exposing this in the API somehow?  Maybe?
+  // Lots of code often want to skip over the internal stuffs.
+  private static final Set<Key<?>> INTERNAL_BINDINGS =
+ ImmutableSet.of(Key.get(Injector.class), Key.get(Stage.class), Key.get(Logger.class));
+
   private final ImmutableList<ProvisionListenerBinding> listenerBindings;

   private final Map<KeyBinding, ProvisionListenerStackCallback<?>> cache
@@ -52,7 +63,12 @@
    */
@SuppressWarnings("unchecked") // the ProvisionListenerStackCallback type always agrees with the passed type
   public <T> ProvisionListenerStackCallback<T> get(Binding<T> binding) {
- return (ProvisionListenerStackCallback<T>) cache.get(new KeyBinding(binding.getKey(), binding));
+    // Never notify any listeners for internal bindings.
+    if (!INTERNAL_BINDINGS.contains(binding.getKey())) {
+      return (ProvisionListenerStackCallback<T>) cache.get(
+          new KeyBinding(binding.getKey(), binding));
+    }
+    return ProvisionListenerStackCallback.emptyListener();
   }

   /**
@@ -82,8 +98,10 @@
         listeners.addAll(provisionBinding.getListeners());
       }
     }
-    if (listeners == null) {
-      listeners = ImmutableList.of();
+    if (listeners == null || listeners.isEmpty()) {
+      // Optimization: don't bother constructing the callback if there are
+      // no listeners.
+      return ProvisionListenerStackCallback.emptyListener();
     }
     return new ProvisionListenerStackCallback<T>(binding, listeners);
   }
=======================================
--- /core/src/com/google/inject/internal/ProvisionListenerStackCallback.java Sun Feb 26 18:23:19 2012 +++ /core/src/com/google/inject/internal/ProvisionListenerStackCallback.java Wed May 15 18:39:15 2013
@@ -16,6 +16,7 @@

 package com.google.inject.internal;

+import com.google.common.collect.ImmutableList;
 import com.google.inject.Binding;
 import com.google.inject.ProvisionException;
 import com.google.inject.spi.DependencyAndSource;
@@ -31,8 +32,17 @@
 final class ProvisionListenerStackCallback<T> {

private static final ProvisionListener EMPTY_LISTENER[] = new ProvisionListener[0];
+  @SuppressWarnings("rawtypes")
+  private static final ProvisionListenerStackCallback<?> EMPTY_CALLBACK =
+ new ProvisionListenerStackCallback(null /* unused, so ok */, ImmutableList.of());
+
   private final ProvisionListener[] listeners;
   private final Binding<T> binding;
+
+  @SuppressWarnings("unchecked")
+  public static <T> ProvisionListenerStackCallback<T> emptyListener() {
+    return (ProvisionListenerStackCallback<T>) EMPTY_CALLBACK;
+  }

public ProvisionListenerStackCallback(Binding<T> binding, List<ProvisionListener> listeners) {
     this.binding = binding;
=======================================
--- /core/src/com/google/inject/spi/ProvisionListener.java Sun Feb 26 18:23:19 2012 +++ /core/src/com/google/inject/spi/ProvisionListener.java Wed May 15 18:39:15 2013
@@ -35,7 +35,9 @@
* Invoked by Guice when an object requires provisioning. Provisioning occurs * when Guice locates and injects the dependencies for a binding. For types * bound to a Provider, provisioning encapsulates the {@link Provider#get} - * method. For other types, provisioning encapsulates the construction of the
+   * method. For toInstance or constant bindings, provisioning encapsulates
+   * the injecting of {@literal @}{@code Inject}ed fields or methods.
+   * For other types, provisioning encapsulates the construction of the
* object. If a type is bound within a {@link Scope}, provisioning depends on * the scope. Types bound in Singleton scope will only be provisioned once. * Types bound in no scope will be provisioned every time they are injected.
=======================================
--- /core/test/com/google/inject/BinderTest.java        Tue Sep 13 10:41:32 2011
+++ /core/test/com/google/inject/BinderTest.java        Wed May 15 18:39:15 2013
@@ -456,6 +456,7 @@
bind(Module.class).annotatedWith(red).toProvider(Providers.<Module>of(null)); bind(Provider.class).annotatedWith(red).toProvider(Providers.<Provider>of(null)); bind(Scope.class).annotatedWith(red).toProvider(Providers.<Scope>of(null)); + bind(Stage.class).annotatedWith(red).toProvider(Providers.<Stage>of(null)); bind(TypeLiteral.class).annotatedWith(red).toProvider(Providers.<TypeLiteral>of(null)); bind(new TypeLiteral<Key<String>>() {}).toProvider(Providers.<Key<String>>of(null));
         }
@@ -471,6 +472,7 @@
           "Binding to core guice framework type is not allowed: Module.",
           "Binding to Provider is not allowed.",
           "Binding to core guice framework type is not allowed: Scope.",
+          "Binding to core guice framework type is not allowed: Stage.",
"Binding to core guice framework type is not allowed: TypeLiteral.",
           "Binding to core guice framework type is not allowed: Key.");
     }
=======================================
--- /core/test/com/google/inject/BindingTest.java       Thu Jul  7 17:34:16 2011
+++ /core/test/com/google/inject/BindingTest.java       Wed May 15 18:39:15 2013
@@ -370,8 +370,7 @@
       }
     });

- assertEquals(ImmutableSet.of(TypeLiteral.get(Stage.class), TypeLiteral.get(D.class)),
-        heardTypes);
+    assertEquals(ImmutableSet.of(TypeLiteral.get(D.class)), heardTypes);
   }

public void testInterfaceToImplementationConstructor() throws NoSuchMethodException {
=======================================
--- /core/test/com/google/inject/ProvisionListenerTest.java Sun Feb 26 18:23:19 2012 +++ /core/test/com/google/inject/ProvisionListenerTest.java Wed May 15 18:39:15 2013
@@ -21,17 +21,21 @@
 import static com.google.inject.name.Names.named;

 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
 import com.google.inject.matcher.AbstractMatcher;
 import com.google.inject.matcher.Matcher;
 import com.google.inject.matcher.Matchers;
 import com.google.inject.name.Named;
 import com.google.inject.spi.DependencyAndSource;
+import com.google.inject.spi.InstanceBinding;
 import com.google.inject.spi.ProvisionListener;
+import com.google.inject.util.Providers;

 import junit.framework.TestCase;

 import java.util.List;
+import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;

 /**
@@ -244,6 +248,8 @@
           throw new RuntimeException(ex);
         }
         bind(LinkedFoo.class).to(Foo.class);
+        bind(Interface.class).toInstance(new Implementation());
+        bindConstant().annotatedWith(named("constant")).to("MyConstant");
       }

       @Provides @Named("pi") Foo provideFooBar() {
@@ -251,6 +257,11 @@
       }
     });

+ // toInstance & constant bindings are notified in random order, at the very beginning.
+    assertEquals(
+ ImmutableSet.of(Key.get(Interface.class), Key.get(String.class, named("constant"))),
+        capturer.getAsSetAndClear());
+
     // simple binding
     assertNotNull(injector.getInstance(Foo.class));
     assertEquals(of(Key.get(Foo.class)), capturer.getAndClear());
@@ -333,6 +344,9 @@
// We don't really care what kind of error you get, we only care you get an error.
     }
   }
+
+  interface Interface {}
+  class Implementation implements Interface {}

   @Singleton static class Sole {}
   static class Many {}
@@ -370,8 +384,24 @@
     public <T> void onProvision(ProvisionInvocation<T> provision) {
       keys.add(provision.getBinding().getKey());
       T provisioned = provision.provision();
+      // InstanceBindings are the only kind of binding where the key can
+      // be an instanceof the provisioned, because it isn't linked to any
+      // direct implementation.  I guess maybe it'd also be possible
+ // with a toConstructor binding... but we don't use that in our tests.
+      if (provision.getBinding() instanceof InstanceBinding) {
+ Class<? super T> expected = provision.getBinding().getKey().getRawType(); + assertTrue("expected instanceof: " + expected + ", but was: " + provisioned,
+            expected.isInstance(provisioned));
+      } else {
assertEquals(provision.getBinding().getKey().getRawType(), provisioned.getClass());
     }
+    }
+
+    Set<Key> getAsSetAndClear() {
+      Set<Key> copy = ImmutableSet.copyOf(keys);
+      keys.clear();
+      return copy;
+    }

     List<Key> getAndClear() {
       List<Key> copy = ImmutableList.copyOf(keys);
@@ -454,8 +484,10 @@

         // Build up a list of asserters for our dependency chains.
         ImmutableList.Builder<Class<?>> chain = ImmutableList.builder();
+        chain.add(Instance.class);
+ bindListener(keyMatcher(Instance.class), new ChainAsserter(pList, chain.build()));

-        chain.add(Instance.class).add(A.class);
+        chain.add(A.class);
bindListener(keyMatcher(A.class), new ChainAsserter(pList, chain.build()));

         chain.add(B.class).add(BImpl.class);
@@ -482,7 +514,8 @@
     });
     Instance instance = injector.getInstance(Instance.class);
     // make sure we're checking all of the chain asserters..
- assertEquals(of(A.class, BImpl.class, C.class, DP.class, D.class, E.class, F.class),
+    assertEquals(
+ of(Instance.class, A.class, BImpl.class, C.class, DP.class, D.class, E.class, F.class),
         pList);
     // and make sure that nothing else was notified that we didn't expect.
     assertEquals(totalList, pList);
@@ -585,5 +618,22 @@
     @SuppressWarnings("unused")
     @Inject F f;
   }
-  private static class F {}
+  private static class F {
+  }
+
+  public void testBindToInjectorWithListeningGivesSaneException() {
+    try {
+      Guice.createInjector(new AbstractModule() {
+        @Override
+        protected void configure() {
+          bindListener(Matchers.any(), new Counter());
+          bind(Injector.class).toProvider(Providers.<Injector>of(null));
+        }
+      });
+      fail();
+    } catch (CreationException ce) {
+      assertContains(
+ ce.getMessage(), "Binding to core guice framework type is not allowed: Injector.");
+    }
+  }
 }
=======================================
--- /core/test/com/google/inject/TypeListenerTest.java Thu Jul 7 17:34:16 2011 +++ /core/test/com/google/inject/TypeListenerTest.java Wed May 15 18:39:15 2013
@@ -596,7 +596,8 @@
     try {
       Guice.createInjector(new AbstractModule() {
         protected void configure() {
- bindListener(Matchers.only(new TypeLiteral<Stage>() {}), new TypeListener() {
+          requestInjection(new Object());
+          bindListener(Matchers.any(), new TypeListener() {
public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
               encounter.addError("There was an error on %s", type);
               encounter.addError(new IllegalArgumentException("whoops!"));
@@ -609,7 +610,7 @@
       fail();
     } catch (CreationException expected) {
       assertContains(expected.getMessage(),
-          "1) There was an error on com.google.inject.Stage",
+          "1) There was an error on java.lang.Object",
           "2) An exception was caught and reported. Message: whoops!",
           "3) And another problem",
           "4) An exception was caught and reported. Message: null",
=======================================
--- /extensions/multibindings/test/com/google/inject/multibindings/SpiUtils.java Thu Jul 7 17:34:16 2011 +++ /extensions/multibindings/test/com/google/inject/multibindings/SpiUtils.java Wed May 15 18:39:15 2013
@@ -500,7 +500,7 @@
return new MapResult<K, V>(k, new BindResult<V>(PROVIDER_INSTANCE, v, null));
   }

-  private static class MapResult<K, V> {
+  static class MapResult<K, V> {
     private final K k;
     private final BindResult<V> v;

@@ -534,7 +534,7 @@
   /** The kind of binding. */
   static enum BindType { INSTANCE, LINKED, PROVIDER_INSTANCE }
   /** The result of the binding. */
-  private static class BindResult<T> {
+  static class BindResult<T> {
     private final BindType type;
     private final Key<? extends T> key;
     private final T instance;

--
You received this message because you are subscribed to the Google Groups 
"google-guice-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to google-guice-dev+unsubscr...@googlegroups.com.
To post to this group, send email to google-guice-dev@googlegroups.com.
Visit this group at http://groups.google.com/group/google-guice-dev?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to