Revision: 1527
Author: sberlin
Date: Thu Mar 10 19:02:39 2011
Log: remove phases from BindingProcessor, refactor so that two different classes do the two different bits, with an abstract superclass managing the shared pieces.
http://code.google.com/p/google-guice/source/detail?r=1527

Added:
 /trunk/core/src/com/google/inject/internal/AbstractBindingProcessor.java
 /trunk/core/src/com/google/inject/internal/CreationListener.java
 /trunk/core/src/com/google/inject/internal/ProcessedBindingData.java
 /trunk/core/src/com/google/inject/internal/UntargettedBindingProcessor.java
Modified:
 /trunk/core/src/com/google/inject/internal/BindingProcessor.java
 /trunk/core/src/com/google/inject/internal/BoundProviderFactory.java
 /trunk/core/src/com/google/inject/internal/ExposedKeyFactory.java
 /trunk/core/src/com/google/inject/internal/FactoryProxy.java
 /trunk/core/src/com/google/inject/internal/InjectorShell.java
 /trunk/core/src/com/google/inject/internal/InternalInjectorCreator.java

=======================================
--- /dev/null
+++ /trunk/core/src/com/google/inject/internal/AbstractBindingProcessor.java Thu Mar 10 19:02:39 2011
@@ -0,0 +1,167 @@
+/**
+ * Copyright (C) 2011 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 java.util.Set;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Binder;
+import com.google.inject.Binding;
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.MembersInjector;
+import com.google.inject.Module;
+import com.google.inject.Provider;
+import com.google.inject.Scope;
+import com.google.inject.TypeLiteral;
+import com.google.inject.internal.util.ImmutableSet;
+import com.google.inject.spi.DefaultBindingTargetVisitor;
+
+/**
+ * Guarantees that processing of Binding elements happens in a sane way.
+ *
+ * @author [email protected] (Sam Berlin)
+ */
+abstract class AbstractBindingProcessor extends AbstractProcessor {
+
+  // It's unfortunate that we have to maintain a blacklist of specific
+  // classes, but we can't easily block the whole package because of
+  // all our unit tests.
+ private static final Set<Class<?>> FORBIDDEN_TYPES = ImmutableSet.<Class<?>>of(
+      AbstractModule.class,
+      Binder.class,
+      Binding.class,
+      Injector.class,
+      Key.class,
+      MembersInjector.class,
+      Module.class,
+      Provider.class,
+      Scope.class,
+      TypeLiteral.class);
+  // TODO(jessewilson): fix BuiltInModule, then add Stage
+
+  protected final ProcessedBindingData bindingData;
+
+ AbstractBindingProcessor(Errors errors, ProcessedBindingData bindingData) {
+    super(errors);
+    this.bindingData = bindingData;
+  }
+
+  protected <T> UntargettedBindingImpl<T> invalidBinding(
+      InjectorImpl injector, Key<T> key, Object source) {
+    return new UntargettedBindingImpl<T>(injector, key, source);
+  }
+
+  protected void putBinding(BindingImpl<?> binding) {
+    Key<?> key = binding.getKey();
+
+    Class<?> rawType = key.getTypeLiteral().getRawType();
+    if (FORBIDDEN_TYPES.contains(rawType)) {
+      errors.cannotBindToGuiceType(rawType.getSimpleName());
+      return;
+    }
+
+    BindingImpl<?> original = injector.getExistingBinding(key);
+    if (original != null) {
+      // If it failed because of an explicit duplicate binding...
+      if (injector.state.getExplicitBinding(key) != null) {
+        try {
+          if(!isOkayDuplicate(original, binding, injector.state)) {
+            errors.bindingAlreadySet(key, original.getSource());
+            return;
+          }
+        } catch(Throwable t) {
+ errors.errorCheckingDuplicateBinding(key, original.getSource(), t);
+          return;
+        }
+      } else {
+        // Otherwise, it failed because of a duplicate JIT binding
+        // in the parent
+        errors.jitBindingAlreadySet(key);
+        return;
+      }
+    }
+
+    // prevent the parent from creating a JIT binding for this key
+    injector.state.parent().blacklist(key, binding.getSource());
+    injector.state.putBinding(key, binding);
+  }
+
+  /**
+ * We tolerate duplicate bindings if one exposes the other or if the two bindings + * are considered duplicates (see {@link Bindings#areDuplicates(BindingImpl, BindingImpl)}.
+   *
+ * @param original the binding in the parent injector (candidate for an exposing binding) + * @param binding the binding to check (candidate for the exposed binding)
+   */
+ private boolean isOkayDuplicate(BindingImpl<?> original, BindingImpl<?> binding, State state) {
+    if (original instanceof ExposedBindingImpl) {
+      ExposedBindingImpl exposed = (ExposedBindingImpl) original;
+ InjectorImpl exposedFrom = (InjectorImpl) exposed.getPrivateElements().getInjector();
+      return (exposedFrom == binding.getInjector());
+    } else {
+ original = (BindingImpl<?>)state.getExplicitBindingsThisLevel().get(binding.getKey()); + // If no original at this level, the original was on a parent, and we don't
+      // allow deduplication between parents & children.
+      if(original == null) {
+        return false;
+      } else {
+        return original.equals(binding);
+      }
+    }
+  }
+
+  private <T> void validateKey(Object source, Key<T> key) {
+    Annotations.checkForMisplacedScopeAnnotations(
+        key.getTypeLiteral().getRawType(), source, errors);
+  }
+
+  /**
+   * Processor for visiting bindings.  Each overriden method that wants to
+   * actually process the binding should call prepareBinding first.
+   */
+ abstract class Processor<T, V> extends DefaultBindingTargetVisitor<T, V> {
+    final Object source;
+    final Key<T> key;
+    final Class<? super T> rawType;
+    Scoping scoping;
+
+    Processor(BindingImpl<T> binding) {
+      source = binding.getSource();
+      key = binding.getKey();
+      rawType = key.getTypeLiteral().getRawType();
+      scoping = binding.getScoping();
+    }
+
+    protected void prepareBinding() {
+      validateKey(source, key);
+      scoping = Scoping.makeInjectable(scoping, injector, errors);
+    }
+
+    protected void scheduleInitialization(final BindingImpl<?> binding) {
+      bindingData.addUninitializedBinding(new Runnable() {
+        public void run() {
+          try {
+ binding.getInjector().initializeBinding(binding, errors.withSource(source));
+          } catch (ErrorsException e) {
+            errors.merge(e.getErrors());
+          }
+        }
+      });
+    }
+  }
+}
=======================================
--- /dev/null
+++ /trunk/core/src/com/google/inject/internal/CreationListener.java Thu Mar 10 19:02:39 2011
@@ -0,0 +1,24 @@
+/**
+ * Copyright (C) 2011 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;
+
+/** Something that is notified upon creation. */
+interface CreationListener {
+
+  /** Notifies that creation should happen. */
+  void notify(Errors errors);
+}
=======================================
--- /dev/null
+++ /trunk/core/src/com/google/inject/internal/ProcessedBindingData.java Thu Mar 10 19:02:39 2011
@@ -0,0 +1,54 @@
+/**
+ * Copyright (C) 2011 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 java.util.List;
+
+import com.google.inject.internal.util.Lists;
+
+/**
+ * Keeps track of creation listeners & uninitialized bindings,
+ * so they can be processed after bindings are recorded.
+ *
+ * @author [email protected] (Sam Berlin)
+ */
+class ProcessedBindingData {
+
+ private final List<CreationListener> creationListeners = Lists.newArrayList(); + private final List<Runnable> uninitializedBindings = Lists.newArrayList();
+
+  void addCreationListener(CreationListener listener) {
+    creationListeners.add(listener);
+  }
+
+  void addUninitializedBinding(Runnable runnable) {
+    uninitializedBindings.add(runnable);
+  }
+
+  void initializeBindings() {
+    for (Runnable initializer : uninitializedBindings) {
+      initializer.run();
+    }
+  }
+
+  void runCreationListeners(Errors errors) {
+    for (CreationListener creationListener : creationListeners) {
+      creationListener.notify(errors);
+    }
+  }
+
+}
=======================================
--- /dev/null
+++ /trunk/core/src/com/google/inject/internal/UntargettedBindingProcessor.java Thu Mar 10 19:02:39 2011
@@ -0,0 +1,69 @@
+/**
+ * Copyright (C) 2011 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.Binding;
+import com.google.inject.spi.UntargettedBinding;
+
+/**
+ * Processes just UntargettedBindings.
+ *
+ * @author [email protected] (Sam Berlin)
+ */
+class UntargettedBindingProcessor extends AbstractBindingProcessor {
+
+ UntargettedBindingProcessor(Errors errors, ProcessedBindingData bindingData) {
+    super(errors, bindingData);
+  }
+
+  @Override
+  public <T> Boolean visit(Binding<T> binding) {
+ return binding.acceptTargetVisitor(new Processor<T, Boolean>((BindingImpl<T>)binding) {
+      public Boolean visit(UntargettedBinding<? extends T> untargetted) {
+        prepareBinding();
+
+        // Error: Missing implementation.
+        // Example: bind(Date.class).annotatedWith(Red.class);
+ // We can't assume abstract types aren't injectable. They may have an
+        // @ImplementedBy annotation or something.
+        if (key.getAnnotationType() != null) {
+          errors.missingImplementation(key);
+          putBinding(invalidBinding(injector, key, source));
+          return true;
+        }
+
+        // This cast is safe after the preceeding check.
+        try {
+          BindingImpl<T> binding = injector.createUninitializedBinding(
+              key, scoping, source, errors, false);
+          scheduleInitialization(binding);
+          putBinding(binding);
+        } catch (ErrorsException e) {
+          errors.merge(e.getErrors());
+          putBinding(invalidBinding(injector, key, source));
+        }
+
+        return true;
+      }
+
+      @Override
+      protected Boolean visitOther(Binding<? extends T> binding) {
+        return false;
+      }
+    });
+  }
+}
=======================================
--- /trunk/core/src/com/google/inject/internal/BindingProcessor.java Thu Mar 10 16:03:01 2011 +++ /trunk/core/src/com/google/inject/internal/BindingProcessor.java Thu Mar 10 19:02:39 2011
@@ -16,19 +16,10 @@

 package com.google.inject.internal;

-import com.google.inject.AbstractModule;
 import com.google.inject.Binder;
 import com.google.inject.Binding;
-import com.google.inject.Injector;
 import com.google.inject.Key;
-import com.google.inject.MembersInjector;
-import com.google.inject.Module;
 import com.google.inject.Provider;
-import com.google.inject.Scope;
-import com.google.inject.TypeLiteral;
-import com.google.inject.internal.util.ImmutableSet;
-import com.google.inject.internal.util.Lists;
-import com.google.inject.spi.BindingTargetVisitor;
 import com.google.inject.spi.ConstructorBinding;
 import com.google.inject.spi.ConvertedConstantBinding;
 import com.google.inject.spi.ExposedBinding;
@@ -40,7 +31,6 @@
 import com.google.inject.spi.ProviderInstanceBinding;
 import com.google.inject.spi.ProviderKeyBinding;
 import com.google.inject.spi.UntargettedBinding;
-import java.util.List;
 import java.util.Set;

 /**
@@ -49,28 +39,18 @@
  * @author [email protected] (Bob Lee)
  * @author [email protected] (Jesse Wilson)
  */
-final class BindingProcessor extends AbstractProcessor {
-
- private final List<CreationListener> creationListeners = Lists.newArrayList();
+final class BindingProcessor extends AbstractBindingProcessor {
+
   private final Initializer initializer;
- private final List<Runnable> uninitializedBindings = Lists.newArrayList();
-
-  enum Phase { PASS_ONE, PASS_TWO; }
-  private Phase phase;
-
-  BindingProcessor(Errors errors, Initializer initializer) {
-    super(errors);
+
+ BindingProcessor(Errors errors, Initializer initializer, ProcessedBindingData bindingData) {
+    super(errors, bindingData);
     this.initializer = initializer;
   }
-
-  void setPhase(Phase phase) {
-    this.phase = phase;
-  }

   @Override public <T> Boolean visit(Binding<T> command) {
-    final Object source = command.getSource();
-
- if (Void.class.equals(command.getKey().getTypeLiteral().getRawType())) {
+    Class<?> rawType = command.getKey().getTypeLiteral().getRawType();
+    if (Void.class.equals(rawType)) {
       if (command instanceof ProviderInstanceBinding
&& ((ProviderInstanceBinding) command).getProviderInstance() instanceof ProviderMethod) {
         errors.voidProviderMethod();
@@ -79,22 +59,15 @@
       }
       return true;
     }
-
-    final Key<T> key = command.getKey();
-    Class<? super T> rawType = key.getTypeLiteral().getRawType();
-
+
     if (rawType == Provider.class) {
       errors.bindingToProvider();
       return true;
     }
-
-    validateKey(command.getSource(), command.getKey());
-
-    final Scoping scoping = Scoping.makeInjectable(
-        ((BindingImpl<?>) command).getScoping(), injector, errors);
-
- return command.acceptTargetVisitor(new BindingTargetVisitor<T, Boolean>() {
+
+ return command.acceptTargetVisitor(new Processor<T, Boolean>((BindingImpl<T>)command) {
       public Boolean visit(ConstructorBinding<? extends T> binding) {
+        prepareBinding();
         try {
ConstructorBindingImpl<T> onInjector = ConstructorBindingImpl.create(injector, key,
               binding.getConstructor(), source, scoping, errors, false);
@@ -108,6 +81,7 @@
       }

       public Boolean visit(InstanceBinding<? extends T> binding) {
+        prepareBinding();
         Set<InjectionPoint> injectionPoints = binding.getInjectionPoints();
         T instance = binding.getInstance();
         Initializable<T> ref = initializer.requestInjection(
@@ -121,6 +95,7 @@
       }

       public Boolean visit(ProviderInstanceBinding<? extends T> binding) {
+        prepareBinding();
         Provider<? extends T> provider = binding.getProviderInstance();
         Set<InjectionPoint> injectionPoints = binding.getInjectionPoints();
         Initializable<Provider<? extends T>> initializable = initializer
@@ -134,10 +109,11 @@
       }

       public Boolean visit(ProviderKeyBinding<? extends T> binding) {
+        prepareBinding();
Key<? extends javax.inject.Provider<? extends T>> providerKey = binding.getProviderKey();
         BoundProviderFactory<T> boundProviderFactory
             = new BoundProviderFactory<T>(injector, providerKey, source);
-        creationListeners.add(boundProviderFactory);
+        bindingData.addCreationListener(boundProviderFactory);
         InternalFactory<? extends T> scopedFactory = Scoping.scope(
key, injector, (InternalFactory<? extends T>) boundProviderFactory, source, scoping);
         putBinding(new LinkedProviderBindingImpl<T>(
@@ -146,13 +122,14 @@
       }

       public Boolean visit(LinkedKeyBinding<? extends T> binding) {
+        prepareBinding();
         Key<? extends T> linkedKey = binding.getLinkedKey();
         if (key.equals(linkedKey)) {
           errors.recursiveBinding();
         }

FactoryProxy<T> factory = new FactoryProxy<T>(injector, key, linkedKey, source);
-        creationListeners.add(factory);
+        bindingData.addCreationListener(factory);
         InternalFactory<? extends T> scopedFactory
             = Scoping.scope(key, injector, factory, source, scoping);
         putBinding(
@@ -160,34 +137,8 @@
         return true;
       }

-      public Boolean visit(UntargettedBinding<? extends T> untargetted) {
-        // Error: Missing implementation.
-        // Example: bind(Date.class).annotatedWith(Red.class);
- // We can't assume abstract types aren't injectable. They may have an
-        // @ImplementedBy annotation or something.
-        if (key.getAnnotationType() != null) {
-          errors.missingImplementation(key);
-          putBinding(invalidBinding(injector, key, source));
-          return true;
-        }
-
-        // We want to do UntargettedBindings in the second pass.
-        if (phase == Phase.PASS_ONE) {
-          return false;
-        }
-
-        // This cast is safe after the preceeding check.
-        try {
-          BindingImpl<T> binding = injector.createUninitializedBinding(
-              key, scoping, source, errors, false);
-          scheduleInitialization(binding);
-          putBinding(binding);
-        } catch (ErrorsException e) {
-          errors.merge(e.getErrors());
-          putBinding(invalidBinding(injector, key, source));
-        }
-
-        return true;
+      public Boolean visit(UntargettedBinding<? extends T> untargetted) {
+        return false;
       }

       public Boolean visit(ExposedBinding<? extends T> binding) {
@@ -201,28 +152,15 @@
       public Boolean visit(ProviderBinding<? extends T> binding) {
throw new IllegalArgumentException("Cannot apply a non-module element");
       }
-
-      private void scheduleInitialization(final BindingImpl<?> binding) {
-        uninitializedBindings.add(new Runnable() {
-          public void run() {
-            try {
- binding.getInjector().initializeBinding(binding, errors.withSource(source));
-            } catch (ErrorsException e) {
-              errors.merge(e.getErrors());
-            }
-          }
-        });
+
+      @Override
+      protected Boolean visitOther(Binding<? extends T> binding) {
+ throw new IllegalStateException("BindingProcessor should override all visitations");
       }
     });
   }

   @Override public Boolean visit(PrivateElements privateElements) {
- // Because we do two passes, we have to ignore the PrivateElements in the second
-    // pass.  Otherwise we end up calling bindExposed twice for each one.
-    if (phase == Phase.PASS_TWO) {
-      return false;
-    }
-
     for (Key<?> key : privateElements.getExposedKeys()) {
       bindExposed(privateElements, key);
     }
@@ -231,108 +169,8 @@

private <T> void bindExposed(PrivateElements privateElements, Key<T> key) { ExposedKeyFactory<T> exposedKeyFactory = new ExposedKeyFactory<T>(key, privateElements);
-    creationListeners.add(exposedKeyFactory);
+    bindingData.addCreationListener(exposedKeyFactory);
     putBinding(new ExposedBindingImpl<T>(
injector, privateElements.getExposedSource(key), key, exposedKeyFactory, privateElements));
   }
-
-  private <T> void validateKey(Object source, Key<T> key) {
-    Annotations.checkForMisplacedScopeAnnotations(
-        key.getTypeLiteral().getRawType(), source, errors);
-  }
-
- <T> UntargettedBindingImpl<T> invalidBinding(InjectorImpl injector, Key<T> key, Object source) {
-    return new UntargettedBindingImpl<T>(injector, key, source);
-  }
-
-  public void initializeBindings() {
-    for (Runnable initializer : uninitializedBindings) {
-      initializer.run();
-    }
-  }
-
-  public void runCreationListeners() {
-    for (CreationListener creationListener : creationListeners) {
-      creationListener.notify(errors);
-    }
-  }
-
-  private void putBinding(BindingImpl<?> binding) {
-    Key<?> key = binding.getKey();
-
-    Class<?> rawType = key.getTypeLiteral().getRawType();
-    if (FORBIDDEN_TYPES.contains(rawType)) {
-      errors.cannotBindToGuiceType(rawType.getSimpleName());
-      return;
-    }
-
-    BindingImpl<?> original = injector.getExistingBinding(key);
-    if (original != null) {
-      // If it failed because of an explicit duplicate binding...
-      if (injector.state.getExplicitBinding(key) != null) {
-        try {
-          if(!isOkayDuplicate(original, binding, injector.state)) {
-            errors.bindingAlreadySet(key, original.getSource());
-            return;
-          }
-        } catch(Throwable t) {
- errors.errorCheckingDuplicateBinding(key, original.getSource(), t);
-          return;
-        }
-      } else {
-        // Otherwise, it failed because of a duplicate JIT binding
-        // in the parent
-        errors.jitBindingAlreadySet(key);
-        return;
-      }
-    }
-
-    // prevent the parent from creating a JIT binding for this key
-    injector.state.parent().blacklist(key, binding.getSource());
-    injector.state.putBinding(key, binding);
-  }
-
-  /**
- * We tolerate duplicate bindings if one exposes the other or if the two bindings - * are considered duplicates (see {@link Bindings#areDuplicates(BindingImpl, BindingImpl)}.
-   *
- * @param original the binding in the parent injector (candidate for an exposing binding) - * @param binding the binding to check (candidate for the exposed binding)
-   */
- private boolean isOkayDuplicate(BindingImpl<?> original, BindingImpl<?> binding, State state) {
-    if (original instanceof ExposedBindingImpl) {
-      ExposedBindingImpl exposed = (ExposedBindingImpl) original;
- InjectorImpl exposedFrom = (InjectorImpl) exposed.getPrivateElements().getInjector();
-      return (exposedFrom == binding.getInjector());
-    } else {
- original = (BindingImpl<?>)state.getExplicitBindingsThisLevel().get(binding.getKey()); - // If no original at this level, the original was on a parent, and we don't
-      // allow deduplication between parents & children.
-      if(original == null) {
-        return false;
-      } else {
-        return original.equals(binding);
-      }
-    }
-  }
-
-  // It's unfortunate that we have to maintain a blacklist of specific
-  // classes, but we can't easily block the whole package because of
-  // all our unit tests.
- private static final Set<Class<?>> FORBIDDEN_TYPES = ImmutableSet.<Class<?>>of(
-      AbstractModule.class,
-      Binder.class,
-      Binding.class,
-      Injector.class,
-      Key.class,
-      MembersInjector.class,
-      Module.class,
-      Provider.class,
-      Scope.class,
-      TypeLiteral.class);
-  // TODO(jessewilson): fix BuiltInModule, then add Stage
-
-  interface CreationListener {
-    void notify(Errors errors);
-  }
-}
+}
=======================================
--- /trunk/core/src/com/google/inject/internal/BoundProviderFactory.java Thu Feb 11 14:07:07 2010 +++ /trunk/core/src/com/google/inject/internal/BoundProviderFactory.java Thu Mar 10 19:02:39 2011
@@ -17,7 +17,6 @@
 package com.google.inject.internal;

 import com.google.inject.Key;
-import com.google.inject.internal.BindingProcessor.CreationListener;
 import com.google.inject.internal.InjectorImpl.JitLimitation;
 import com.google.inject.spi.Dependency;

=======================================
--- /trunk/core/src/com/google/inject/internal/ExposedKeyFactory.java Thu Feb 11 14:07:07 2010 +++ /trunk/core/src/com/google/inject/internal/ExposedKeyFactory.java Thu Mar 10 19:02:39 2011
@@ -24,7 +24,7 @@
* This factory exists in a parent injector. When invoked, it retrieves its value from a child
  * injector.
  */
-final class ExposedKeyFactory<T> implements InternalFactory<T>, BindingProcessor.CreationListener { +final class ExposedKeyFactory<T> implements InternalFactory<T>, CreationListener {
   private final Key<T> key;
   private final PrivateElements privateElements;
   private BindingImpl<T> delegate;
=======================================
--- /trunk/core/src/com/google/inject/internal/FactoryProxy.java Sat Jul 3 08:51:31 2010 +++ /trunk/core/src/com/google/inject/internal/FactoryProxy.java Thu Mar 10 19:02:39 2011
@@ -25,7 +25,7 @@
* A placeholder which enables us to swap in the real factory once the injector is created. * Used for a linked binding, so that getting the linked binding returns the link's factory.
  */
-final class FactoryProxy<T> implements InternalFactory<T>, BindingProcessor.CreationListener { +final class FactoryProxy<T> implements InternalFactory<T>, CreationListener {

   private final InjectorImpl injector;
   private final Key<T> key;
=======================================
--- /trunk/core/src/com/google/inject/internal/InjectorShell.java Thu Mar 10 16:03:01 2011 +++ /trunk/core/src/com/google/inject/internal/InjectorShell.java Thu Mar 10 19:02:39 2011
@@ -24,7 +24,6 @@
 import static com.google.inject.Scopes.SINGLETON;
 import com.google.inject.Singleton;
 import com.google.inject.Stage;
-import com.google.inject.internal.BindingProcessor.Phase;
 import com.google.inject.internal.InjectorImpl.InjectorOptions;
 import com.google.inject.internal.util.ImmutableSet;
 import com.google.inject.internal.util.Lists;
@@ -51,10 +50,8 @@

   private final List<Element> elements;
   private final InjectorImpl injector;
-  private final PrivateElements privateElements;

private InjectorShell(Builder builder, List<Element> elements, InjectorImpl injector) {
-    this.privateElements = builder.privateElements;
     this.elements = elements;
     this.injector = injector;
   }
@@ -120,8 +117,11 @@
* returned if any modules contain {@link Binder#newPrivateBinder private environments}. The
      * primary injector will be first in the returned list.
      */
-    List<InjectorShell> build(BindingProcessor bindingProcessor,
-        Stopwatch stopwatch, Errors errors) {
+    List<InjectorShell> build(
+        Initializer initializer,
+        ProcessedBindingData bindingData,
+        Stopwatch stopwatch,
+        Errors errors) {
       checkState(stage != null, "Stage not initialized");
checkState(privateElements == null || parent != null, "PrivateElements with no parent");
       checkState(state != null, "no state. Did you remember to lock() ?");
@@ -171,14 +171,11 @@
       bindInjector(injector);
       bindLogger(injector);

- // Do two passes over our bindings -- first to get all non UntargettedBindings, - // then to get the only UntargettedBindings. This is necessary because - // UntargettedBindings can create JIT bindings and need all their other
-      // dependencies set up ahead of time.
-      bindingProcessor.setPhase(Phase.PASS_ONE);
-      bindingProcessor.process(injector, elements);
-      bindingProcessor.setPhase(Phase.PASS_TWO);
-      bindingProcessor.process(injector, elements);
+      // Process all normal bindings, then UntargettedBindings.
+ // This is necessary because UntargettedBindings can create JIT bindings
+      // and need all their other dependencies set up ahead of time.
+ new BindingProcessor(errors, initializer, bindingData).process(injector, elements); + new UntargettedBindingProcessor(errors, bindingData).process(injector, elements);
       stopwatch.resetAndLog("Binding creation");

       List<InjectorShell> injectorShells = Lists.newArrayList();
@@ -188,7 +185,7 @@
PrivateElementProcessor processor = new PrivateElementProcessor(errors);
       processor.process(injector, elements);
       for (Builder builder : processor.getInjectorShellBuilders()) {
- injectorShells.addAll(builder.build(bindingProcessor, stopwatch, errors)); + injectorShells.addAll(builder.build(initializer, bindingData, stopwatch, errors));
       }
       stopwatch.resetAndLog("Private environment creation");

=======================================
--- /trunk/core/src/com/google/inject/internal/InternalInjectorCreator.java Sun Dec 12 18:44:36 2010 +++ /trunk/core/src/com/google/inject/internal/InternalInjectorCreator.java Thu Mar 10 19:02:39 2011
@@ -61,7 +61,7 @@
   private final Errors errors = new Errors();

   private final Initializer initializer = new Initializer();
-  private final BindingProcessor bindingProcesor;
+  private final ProcessedBindingData bindingData;
   private final InjectionRequestProcessor injectionRequestProcessor;

private final InjectorShell.Builder shellBuilder = new InjectorShell.Builder();
@@ -69,7 +69,7 @@

   public InternalInjectorCreator() {
injectionRequestProcessor = new InjectionRequestProcessor(errors, initializer);
-    bindingProcesor = new BindingProcessor(errors, initializer);
+    bindingData = new ProcessedBindingData();
   }

   public InternalInjectorCreator stage(Stage stage) {
@@ -100,7 +100,7 @@
// Synchronize while we're building up the bindings and other injector state. This ensures that // the JIT bindings in the parent injector don't change while we're being built
     synchronized (shellBuilder.lock()) {
-      shells = shellBuilder.build(bindingProcesor, stopwatch, errors);
+ shells = shellBuilder.build(initializer, bindingData, stopwatch, errors);
       stopwatch.resetAndLog("Injector construction");

       initializeStatically();
@@ -119,7 +119,7 @@

   /** Initialize and validate everything. */
   private void initializeStatically() {
-    bindingProcesor.initializeBindings();
+    bindingData.initializeBindings();
     stopwatch.resetAndLog("Binding initialization");

     for (InjectorShell shell : shells) {
@@ -130,7 +130,7 @@
     injectionRequestProcessor.process(shells);
     stopwatch.resetAndLog("Collecting injection requests");

-    bindingProcesor.runCreationListeners();
+    bindingData.runCreationListeners(errors);
     stopwatch.resetAndLog("Binding validation");

     injectionRequestProcessor.validate();

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