Revision: 1512
Author: sberlin
Date: Wed Mar 2 05:53:17 2011
Log: issue 610 - let requireExplicitBindings still allow TypeConverters to
create ConvertedConstantBindings.
http://code.google.com/p/google-guice/source/detail?r=1512
Modified:
/trunk/core/src/com/google/inject/internal/InjectorImpl.java
/trunk/core/test/com/google/inject/JitBindingsTest.java
/trunk/core/test/com/google/inject/TypeConversionTest.java
=======================================
--- /trunk/core/src/com/google/inject/internal/InjectorImpl.java Sat Feb 26
16:02:03 2011
+++ /trunk/core/src/com/google/inject/internal/InjectorImpl.java Wed Mar 2
05:53:17 2011
@@ -232,11 +232,7 @@
private <T> BindingImpl<T> getJustInTimeBinding(Key<T> key, Errors
errors, JitLimitation jitType)
throws ErrorsException {
- boolean jitOverride = isProvider(key) || isTypeLiteral(key) ||
isMembersInjector(key);
- if(options.jitDisabled && jitType == JitLimitation.NO_JIT
&& !jitOverride) {
- throw errors.jitDisabled(key).toException();
- }
-
+ boolean jitOverride = isProvider(key) || isTypeLiteral(key) ||
isMembersInjector(key);
synchronized (state.lock()) {
// first try to find a JIT binding that we've already created
for (InjectorImpl injector = this; injector != null; injector =
injector.parent) {
@@ -244,15 +240,20 @@
BindingImpl<T> binding = (BindingImpl<T>)
injector.jitBindings.get(key);
if (binding != null) {
- return binding;
+ // If we found a JIT binding and we don't allow them,
+ // fail. (But allow bindings created through TypeConverters.)
+ if (options.jitDisabled
+ && jitType == JitLimitation.NO_JIT
+ && !jitOverride
+ && !(binding instanceof ConvertedConstantBindingImpl)) {
+ throw errors.jitDisabled(key).toException();
+ } else {
+ return binding;
+ }
}
}
- if(options.jitDisabled && jitType !=
JitLimitation.NEW_OR_EXISTING_JIT && !jitOverride) {
- throw errors.jitDisabled(key).toException();
- } else {
- return createJustInTimeBindingRecursive(key, errors);
- }
+ return createJustInTimeBindingRecursive(key, errors,
options.jitDisabled, jitType);
}
}
@@ -752,12 +753,13 @@
* Attempts to create a just-in-time binding for {@code key} in the root
injector, falling back to
* other ancestor injectors until this injector is tried.
*/
- private <T> BindingImpl<T> createJustInTimeBindingRecursive(Key<T> key,
Errors errors)
- throws ErrorsException {
+ private <T> BindingImpl<T> createJustInTimeBindingRecursive(Key<T> key,
Errors errors,
+ boolean jitDisabled, JitLimitation jitType) throws ErrorsException {
// ask the parent to create the JIT binding
- if (parent != null && !parent.options.jitDisabled) {
+ if (parent != null) {
try {
- return parent.createJustInTimeBindingRecursive(key, new Errors());
+ return parent.createJustInTimeBindingRecursive(key, new Errors(),
jitDisabled,
+ parent.options.jitDisabled ? JitLimitation.NO_JIT : jitType);
} catch (ErrorsException ignored) {
}
}
@@ -767,7 +769,7 @@
throw errors.childBindingAlreadySet(key, sources).toException();
}
- BindingImpl<T> binding = createJustInTimeBinding(key, errors);
+ BindingImpl<T> binding = createJustInTimeBinding(key, errors,
jitDisabled, jitType);
state.parent().blacklist(key, binding.getSource());
jitBindings.put(key, binding);
return binding;
@@ -786,8 +788,8 @@
*
* @throws com.google.inject.internal.ErrorsException if the binding
cannot be created.
*/
- private <T> BindingImpl<T> createJustInTimeBinding(Key<T> key, Errors
errors)
- throws ErrorsException {
+ private <T> BindingImpl<T> createJustInTimeBinding(Key<T> key, Errors
errors,
+ boolean jitDisabled, JitLimitation jitType) throws ErrorsException {
int numErrorsBefore = errors.size();
if (state.isBlacklisted(key)) {
@@ -818,6 +820,12 @@
if (convertedBinding != null) {
return convertedBinding;
}
+
+ if (!isTypeLiteral(key)
+ && jitDisabled
+ && jitType != JitLimitation.NEW_OR_EXISTING_JIT) {
+ throw errors.jitDisabled(key).toException();
+ }
// If the key has an annotation...
if (key.getAnnotationType() != null) {
=======================================
--- /trunk/core/test/com/google/inject/JitBindingsTest.java Tue Dec 14
06:08:21 2010
+++ /trunk/core/test/com/google/inject/JitBindingsTest.java Wed Mar 2
05:53:17 2011
@@ -40,6 +40,12 @@
private String jitFailed(TypeLiteral<?> clazz) {
return "Explicit bindings are required and " + clazz + " is not
explicitly bound.";
}
+
+ private String inChildMessage(Class<?> clazz) {
+ return "Unable to create binding for "
+ + clazz.getName()
+ + ". It was already configured on one or more child injectors or
private modules";
+ }
public void testLinkedBindingWorks() {
Injector injector = Guice.createInjector(new AbstractModule() {
@@ -317,7 +323,7 @@
});
ensureWorks(child, Foo.class, Bar.class);
ensureFails(child, ALLOW_BINDING, FooImpl.class);
- ensureFails(parent, FAIL_ALL, FooImpl.class, FooBar.class, Foo.class);
// parent still doesn't have these
+ ensureInChild(parent, FooImpl.class, FooBar.class, Foo.class);
Injector grandchild = child.createChildInjector(new AbstractModule() {
@Override
@@ -328,7 +334,7 @@
ensureWorks(grandchild, FooBar.class, Foo.class, Bar.class);
ensureFails(grandchild, ALLOW_BINDING, FooImpl.class);
ensureFails(child, ALLOW_BINDING, FooImpl.class);
- ensureFails(parent, FAIL_ALL, FooImpl.class, FooBar.class, Foo.class);
// parent still doesn't have these
+ ensureInChild(parent, FooImpl.class, FooBar.class, Foo.class);
}
public void testChildInjectorAddsOption() {
@@ -418,6 +424,20 @@
assertContains(expected.getMessage(), "1) " + jitFailed(Bar.class));
assertTrue(expected.getMessage(), !expected.getMessage().contains("2) "));
}
+
+ Injector injector = Guice.createInjector(new AbstractModule() {
+ protected void configure() {
+ binder().requireExplicitBindings();
+
+ install(new PrivateModule() {
+ public void configure() {
+ bind(Foo.class).to(FooImpl.class);
+ expose(Foo.class);
+ }
+ });
+ }
+ });
+ ensureInChild(injector, FooImpl.class);
}
public void testPrivateModuleAddsOption() {
@@ -552,6 +572,34 @@
}
}
}
+
+ private void ensureInChild(Injector injector, Class<?>... classes) {
+ for(int i = 0; i < classes.length; i++) {
+ try {
+ injector.getInstance(classes[i]);
+ fail("should have failed tring to retrieve class: " + classes[i]);
+ } catch(ConfigurationException expected) {
+ assertContains(expected.getMessage(), "1) " +
inChildMessage(classes[i]));
+
assertTrue(expected.getMessage(), !expected.getMessage().contains("2) "));
+ }
+
+ try {
+ injector.getProvider(classes[i]);
+ fail("should have failed tring to retrieve class: " + classes[i]);
+ } catch(ConfigurationException expected) {
+ assertContains(expected.getMessage(), "1) " +
inChildMessage(classes[i]));
+
assertTrue(expected.getMessage(), !expected.getMessage().contains("2) "));
+ }
+
+ try {
+ injector.getBinding(classes[i]);
+ fail("should have failed tring to retrieve class: " + classes[i]);
+ } catch(ConfigurationException expected) {
+ assertContains(expected.getMessage(), "1) " +
inChildMessage(classes[i]));
+
assertTrue(expected.getMessage(), !expected.getMessage().contains("2) "));
+ }
+ }
+ }
private static interface Foo {}
private static class FooImpl implements Foo {}
=======================================
--- /trunk/core/test/com/google/inject/TypeConversionTest.java Thu Nov 18
18:33:32 2010
+++ /trunk/core/test/com/google/inject/TypeConversionTest.java Wed Mar 2
05:53:17 2011
@@ -94,6 +94,39 @@
}
});
+ Foo foo = injector.getInstance(Foo.class);
+
+ checkNumbers(
+ foo.integerField,
+ foo.primitiveIntField,
+ foo.longField,
+ foo.primitiveLongField,
+ foo.byteField,
+ foo.primitiveByteField,
+ foo.shortField,
+ foo.primitiveShortField,
+ foo.floatField,
+ foo.primitiveFloatField,
+ foo.doubleField,
+ foo.primitiveDoubleField
+ );
+
+ assertEquals(Bar.TEE, foo.enumField);
+ assertEquals(Foo.class, foo.classField);
+ }
+
+ public void testConstantInjectionWithExplicitBindingsRequired() throws
CreationException {
+ Injector injector = Guice.createInjector(new AbstractModule() {
+ protected void configure() {
+ binder().requireExplicitBindings();
+ bind(Foo.class);
+ bindConstant().annotatedWith(NumericValue.class).to("5");
+ bindConstant().annotatedWith(BooleanValue.class).to("true");
+ bindConstant().annotatedWith(EnumValue.class).to("TEE");
+
bindConstant().annotatedWith(ClassName.class).to(Foo.class.getName());
+ }
+ });
+
Foo foo = injector.getInstance(Foo.class);
checkNumbers(
--
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.