Skip to content

Commit a0b4d16

Browse files
jessevbGuice Team
authored andcommitted
Add a moduleInstance parameter to the ModuleAnnotatedMethodScanner. This is useful in some cases where the scanner bindings need more information from the module currently being scanned.
PiperOrigin-RevId: 615788414
1 parent d46b395 commit a0b4d16

File tree

4 files changed

+92
-4
lines changed

4 files changed

+92
-4
lines changed

core/src/com/google/inject/internal/ProviderMethodsModule.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,8 @@ private <T> ProviderMethod<T> createProviderMethod(
295295
Key<T> key = getKey(errors, returnType, method, method.getAnnotations());
296296
boolean prepareMethodError = false;
297297
try {
298-
key = scanner.prepareMethod(binder, annotation, key, point);
298+
key =
299+
scanner.prepareMethod(binder, annotation, key, point, isStaticModule() ? null : delegate);
299300
} catch (Throwable t) {
300301
prepareMethodError = true;
301302
binder.addError(t);

core/src/com/google/inject/spi/ElementSource.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public final class ElementSource {
4747
final ElementSource originalElementSource;
4848

4949
/**
50-
* Wheather the originalElementSource was set externaly (untrusted) or by Guice internals
50+
* Whether the originalElementSource was set externally (untrusted) or by Guice internals
5151
* (trusted).
5252
*
5353
* <p>External code can set the originalElementSource to an arbitrary ElementSource via

core/src/com/google/inject/spi/ModuleAnnotatedMethodScanner.java

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import com.google.inject.Key;
2121
import java.lang.annotation.Annotation;
2222
import java.util.Set;
23+
import javax.annotation.Nullable;
2324

2425
/**
2526
* Allows extensions to scan modules for annotated methods and bind those methods as providers,
@@ -53,7 +54,45 @@ public abstract class ModuleAnnotatedMethodScanner {
5354
* <p>If {@code injectionPoint} represents an {@code abstract} method, {@code null} must be
5455
* returned from this method. This scanner can use {@code binder} to bind alternative bindings in
5556
* place of the abstract method.
57+
*
58+
* @deprecated Prefer overriding the overload that takes `Object moduleInstance` instead. If not
59+
* overridden, that method will invoke this one to aid in backwards compatibility.
60+
*/
61+
@Deprecated
62+
public <T> Key<T> prepareMethod(
63+
Binder binder, Annotation annotation, Key<T> key, InjectionPoint injectionPoint) {
64+
throw new IllegalStateException(
65+
"'prepareMethod' not implemented, one override must be implemented.");
66+
}
67+
68+
/**
69+
* Prepares a method for binding. This {@code key} parameter is the key discovered from looking at
70+
* the binding annotation and return value of the method. Implementations can modify the key to
71+
* instead bind to another key. For example, Multibinder may want to change
72+
* {@code @ProvidesIntoSet String provideFoo()} to bind into a unique Key within the multibinder
73+
* instead of binding {@code String}.
74+
*
75+
* <p>The injection point and annotation are provided in case the implementation wants to set the
76+
* key based on the property of the annotation or if any additional preparation is needed for any
77+
* of the dependencies. The annotation is guaranteed to be an instance of one the classes returned
78+
* by {@link #annotationClasses}.
79+
*
80+
* <p>Returning null will cause Guice to skip this method, so that it is not bound to any key.
81+
*
82+
* <p>If {@code injectionPoint} represents an {@code abstract} method, {@code null} must be
83+
* returned from this method. This scanner can use {@code binder} to bind alternative bindings in
84+
* place of the abstract method.
85+
*
86+
* <p>The {@code moduleInstance} parameter contains the Module instance that is currently being
87+
* scanned, which may be null if the methods were discovered on Module class objects (as opposed
88+
* to module instances).
5689
*/
57-
public abstract <T> Key<T> prepareMethod(
58-
Binder binder, Annotation annotation, Key<T> key, InjectionPoint injectionPoint);
90+
public <T> Key<T> prepareMethod(
91+
Binder binder,
92+
Annotation annotation,
93+
Key<T> key,
94+
InjectionPoint injectionPoint,
95+
@Nullable Object moduleInstance) {
96+
return prepareMethod(binder, annotation, key, injectionPoint);
97+
}
5998
}

core/test/com/google/inject/spi/ModuleAnnotatedMethodScannerTest.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,6 +1035,54 @@ String privateString() {
10351035
.isEqualTo(scanner);
10361036
}
10371037

1038+
static class DelegatingScanner extends ModuleAnnotatedMethodScanner {
1039+
Object delegate = null;
1040+
1041+
@Override
1042+
public Set<? extends Class<? extends Annotation>> annotationClasses() {
1043+
return ImmutableSet.of(TestProvides.class);
1044+
}
1045+
1046+
@Override
1047+
public <T> Key<T> prepareMethod(
1048+
Binder binder,
1049+
Annotation annotation,
1050+
Key<T> key,
1051+
InjectionPoint injectionPoint,
1052+
Object delegate) {
1053+
this.delegate = delegate;
1054+
return key;
1055+
}
1056+
}
1057+
1058+
@Test
1059+
public void scannerPropagatesTheDelegateObject() {
1060+
DelegatingScanner scanner = new DelegatingScanner();
1061+
AbstractModule module =
1062+
new AbstractModule() {
1063+
@TestProvides
1064+
String provideString() {
1065+
return "foo";
1066+
}
1067+
};
1068+
Guice.createInjector(scannerModule(scanner), module);
1069+
assertThat(scanner.delegate).isSameInstanceAs(module);
1070+
}
1071+
1072+
static class StaticProvider extends AbstractModule {
1073+
@TestProvides
1074+
static String provideString() {
1075+
return "foo";
1076+
}
1077+
}
1078+
1079+
@Test
1080+
public void staticScannerPropagatesNullDelegateObject() {
1081+
DelegatingScanner scanner = new DelegatingScanner();
1082+
Guice.createInjector(ProviderMethodsModule.forModule(StaticProvider.class, scanner));
1083+
assertThat(scanner.delegate).isNull();
1084+
}
1085+
10381086
ModuleAnnotatedMethodScanner getSourceScanner(Binding<?> binding) {
10391087
return ((ElementSource) binding.getSource()).scanner;
10401088
}

0 commit comments

Comments
 (0)