Skip to content
Permalink
Browse files

Record static injection requests, instance injection requests, member…

…s injector lookups and all provider lookups, so we can record more dependency information after the injector is built.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=236366255
  • Loading branch information...
sameb authored and ronshapiro committed Mar 1, 2019
1 parent 06f72cf commit dafa4b0bec4e7ec5e1df75e3fb9a2fdf4920921a
@@ -22,14 +22,18 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.inject.Binding;
import com.google.inject.Key;
import com.google.inject.Scope;
import com.google.inject.TypeLiteral;
import com.google.inject.spi.InjectionRequest;
import com.google.inject.spi.MembersInjectorLookup;
import com.google.inject.spi.ModuleAnnotatedMethodScannerBinding;
import com.google.inject.spi.ProviderLookup;
import com.google.inject.spi.ProvisionListenerBinding;
import com.google.inject.spi.ScopeBinding;
import com.google.inject.spi.StaticInjectionRequest;
import com.google.inject.spi.TypeConverterBinding;
import com.google.inject.spi.TypeListenerBinding;
import java.lang.annotation.Annotation;
@@ -49,7 +53,10 @@
private final Map<Key<?>, Binding<?>> explicitBindings =
Collections.unmodifiableMap(explicitBindingsMutable);
private final Map<Class<? extends Annotation>, ScopeBinding> scopes = Maps.newHashMap();
private final List<ProviderLookup<?>> lookups = Lists.newArrayList();
private final Set<ProviderLookup<?>> providerLookups = Sets.newLinkedHashSet();
private final Set<StaticInjectionRequest> staticInjectionRequests = Sets.newLinkedHashSet();
private final Set<MembersInjectorLookup<?>> membersInjectorLookups = Sets.newLinkedHashSet();
private final Set<InjectionRequest<?>> injectionRequests = Sets.newLinkedHashSet();
private final List<TypeConverterBinding> converters = Lists.newArrayList();
/*if[AOP]*/
private final List<MethodAspect> methodAspects = Lists.newArrayList();
@@ -90,12 +97,42 @@ public void putBinding(Key<?> key, BindingImpl<?> binding) {

@Override
public void putProviderLookup(ProviderLookup<?> lookup) {
lookups.add(lookup);
providerLookups.add(lookup);
}

@Override
public List<ProviderLookup<?>> getProviderLookupsThisLevel() {
return lookups;
public Set<ProviderLookup<?>> getProviderLookupsThisLevel() {
return providerLookups;
}

@Override
public void putStaticInjectionRequest(StaticInjectionRequest staticInjectionRequest) {
staticInjectionRequests.add(staticInjectionRequest);
}

@Override
public Set<StaticInjectionRequest> getStaticInjectionRequestsThisLevel() {
return staticInjectionRequests;
}

@Override
public void putInjectionRequest(InjectionRequest<?> injectionRequest) {
injectionRequests.add(injectionRequest);
}

@Override
public Set<InjectionRequest<?>> getInjectionRequestsThisLevel() {
return injectionRequests;
}

@Override
public void putMembersInjectorLookup(MembersInjectorLookup<?> membersInjectorLookup) {
membersInjectorLookups.add(membersInjectorLookup);
}

@Override
public Set<MembersInjectorLookup<?>> getMembersInjectorLookupsThisLevel() {
return membersInjectorLookups;
}

@Override
@@ -20,6 +20,7 @@
import com.google.common.collect.Lists;
import com.google.inject.ConfigurationException;
import com.google.inject.Stage;
import com.google.inject.TypeLiteral;
import com.google.inject.spi.InjectionPoint;
import com.google.inject.spi.InjectionRequest;
import com.google.inject.spi.StaticInjectionRequest;
@@ -46,6 +47,7 @@
@Override
public Boolean visit(StaticInjectionRequest request) {
staticInjections.add(new StaticInjection(injector, request));
injector.state.putStaticInjectionRequest(request);
return true;
}

@@ -61,6 +63,16 @@ public Boolean visit(InjectionRequest<?> request) {

initializer.requestInjection(
injector, request.getInstance(), null, request.getSource(), injectionPoints);
// When recreating the injection request, we revise the TypeLiteral to be the type
// of the instance. This is because currently Guice ignores the user's TypeLiteral
// when determining the types for members injection.
// If/when this is fixed, we can report the exact type back to the user.
// (Otherwise the injection points exposed from the request may be wrong.)
injector.state.putInjectionRequest(
new InjectionRequest<>(
request.getSource(),
TypeLiteral.get(request.getInstance().getClass()),
/* instance= */ null));
return true;
}

@@ -977,6 +977,9 @@ private void removeFailedJitBinding(Binding<?> binding, InjectionPoint ip) {
elements.addAll(state.getTypeListenerBindingsThisLevel());
elements.addAll(state.getProvisionListenerBindingsThisLevel());
elements.addAll(state.getScannerBindingsThisLevel());
elements.addAll(state.getStaticInjectionRequestsThisLevel());
elements.addAll(state.getMembersInjectorLookupsThisLevel());
elements.addAll(state.getInjectionRequestsThisLevel());

return elements.build();
}
@@ -39,6 +39,7 @@
MembersInjector<T> membersInjector =
injector.membersInjectorStore.get(lookup.getType(), errors);
lookup.initializeDelegate(membersInjector);
injector.state.putMembersInjectorLookup(lookup);
} catch (ErrorsException e) {
errors.merge(e.getErrors()); // TODO: source
}
@@ -52,11 +53,7 @@
try {
Provider<T> provider = injector.getProviderOrThrow(lookup.getDependency(), errors);
lookup.initializeDelegate(provider);
// only remember ProviderLookups that are based on injection points,
// since those are the only worthwhile ones that can be examined later.
if (lookup.getDependency().getInjectionPoint() != null) {
injector.state.putProviderLookup(lookup);
}
injector.state.putProviderLookup(lookup);
} catch (ErrorsException e) {
errors.merge(e.getErrors()); // TODO: source
}
@@ -23,10 +23,13 @@
import com.google.inject.Key;
import com.google.inject.Scope;
import com.google.inject.TypeLiteral;
import com.google.inject.spi.InjectionRequest;
import com.google.inject.spi.MembersInjectorLookup;
import com.google.inject.spi.ModuleAnnotatedMethodScannerBinding;
import com.google.inject.spi.ProviderLookup;
import com.google.inject.spi.ProvisionListenerBinding;
import com.google.inject.spi.ScopeBinding;
import com.google.inject.spi.StaticInjectionRequest;
import com.google.inject.spi.TypeConverterBinding;
import com.google.inject.spi.TypeListenerBinding;
import java.lang.annotation.Annotation;
@@ -71,7 +74,37 @@ public void putProviderLookup(ProviderLookup<?> lookup) {
}

@Override
public List<ProviderLookup<?>> getProviderLookupsThisLevel() {
public Set<ProviderLookup<?>> getProviderLookupsThisLevel() {
throw new UnsupportedOperationException();
}

@Override
public void putStaticInjectionRequest(StaticInjectionRequest staticInjectionRequest) {
throw new UnsupportedOperationException();
}

@Override
public Set<StaticInjectionRequest> getStaticInjectionRequestsThisLevel() {
throw new UnsupportedOperationException();
}

@Override
public Set<InjectionRequest<?>> getInjectionRequestsThisLevel() {
throw new UnsupportedOperationException();
}

@Override
public Set<MembersInjectorLookup<?>> getMembersInjectorLookupsThisLevel() {
throw new UnsupportedOperationException();
}

@Override
public void putInjectionRequest(InjectionRequest<?> injectionRequest) {
throw new UnsupportedOperationException();
}

@Override
public void putMembersInjectorLookup(MembersInjectorLookup<?> membersInjectorLookup) {
throw new UnsupportedOperationException();
}

@@ -200,10 +233,22 @@ public Object lock() {

void putProviderLookup(ProviderLookup<?> lookup);

List<ProviderLookup<?>> getProviderLookupsThisLevel();
Set<ProviderLookup<?>> getProviderLookupsThisLevel();

void putStaticInjectionRequest(StaticInjectionRequest staticInjectionRequest);

Set<StaticInjectionRequest> getStaticInjectionRequestsThisLevel();

ScopeBinding getScopeBinding(Class<? extends Annotation> scopingAnnotation);

void putInjectionRequest(InjectionRequest<?> injectionRequest);

Set<InjectionRequest<?>> getInjectionRequestsThisLevel();

void putMembersInjectorLookup(MembersInjectorLookup<?> membersInjectorLookup);

Set<MembersInjectorLookup<?>> getMembersInjectorLookupsThisLevel();

void putScopeBinding(Class<? extends Annotation> annotationType, ScopeBinding scope);

Collection<ScopeBinding> getScopeBindingsThisLevel();
@@ -17,6 +17,7 @@
package com.google.inject.spi;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.inject.internal.InternalFlags.getIncludeStackTraceOption;

import com.google.common.collect.ImmutableList;
@@ -236,11 +237,13 @@ public void bindScope(Class<? extends Annotation> annotationType, Scope scope) {
@Override
@SuppressWarnings("unchecked") // it is safe to use the type literal for the raw type
public void requestInjection(Object instance) {
checkNotNull(instance, "instance");
requestInjection((TypeLiteral<Object>) TypeLiteral.get(instance.getClass()), instance);
}

@Override
public <T> void requestInjection(TypeLiteral<T> type, T instance) {
checkNotNull(instance, "instance");
elements.add(
new InjectionRequest<T>(
getElementSource(), MoreTypes.canonicalizeForKey(type), instance));
@@ -18,6 +18,7 @@

import static com.google.common.base.Preconditions.checkNotNull;

import com.google.common.base.Objects;
import com.google.inject.Binder;
import com.google.inject.ConfigurationException;
import com.google.inject.TypeLiteral;
@@ -43,14 +44,18 @@
public InjectionRequest(Object source, TypeLiteral<T> type, T instance) {
this.source = checkNotNull(source, "source");
this.type = checkNotNull(type, "type");
this.instance = checkNotNull(instance, "instance");
this.instance = instance;
}

@Override
public Object getSource() {
return source;
}

/**
* Returns the instance that injection is being requested on. This may be null for injection
* requests returned from an Injector, to allow the injector to reclaim memory.
*/
public T getInstance() {
return instance;
}
@@ -72,7 +77,8 @@ public T getInstance() {
* the valid injection points.
*/
public Set<InjectionPoint> getInjectionPoints() throws ConfigurationException {
return InjectionPoint.forInstanceMethodsAndFields(instance.getClass());
return InjectionPoint.forInstanceMethodsAndFields(
instance != null ? TypeLiteral.get(instance.getClass()) : type);
}

@Override
@@ -84,4 +90,17 @@ public T getInstance() {
public void applyTo(Binder binder) {
binder.withSource(getSource()).requestInjection(type, instance);
}

@Override
public boolean equals(Object obj) {
return obj instanceof InjectionRequest
&& Objects.equal(((InjectionRequest<?>) obj).instance, instance)
&& ((InjectionRequest<?>) obj).type.equals(type)
&& ((InjectionRequest<?>) obj).source.equals(source);
}

@Override
public int hashCode() {
return Objects.hashCode(type, source);
}
}
@@ -19,9 +19,12 @@
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;

import com.google.common.base.Objects;
import com.google.inject.Binder;
import com.google.inject.ConfigurationException;
import com.google.inject.MembersInjector;
import com.google.inject.TypeLiteral;
import java.util.Set;

/**
* A lookup of the members injector for a type. Lookups are created explicitly in a module using
@@ -84,6 +87,21 @@ public void applyTo(Binder binder) {
return delegate;
}

/**
* Returns the instance methods and fields that will be injected to fulfill this request.
*
* @return a possibly empty set of injection points. The set has a specified iteration order. All
* fields are returned and then all methods. Within the fields, supertype fields are returned
* before subtype fields. Similarly, supertype methods are returned before subtype methods.
* @throws ConfigurationException if there is a malformed injection point on the class of {@code
* instance}, such as a field with multiple binding annotations. The exception's {@link
* ConfigurationException#getPartialValue() partial value} is a {@code Set<InjectionPoint>} of
* the valid injection points.
*/
public Set<InjectionPoint> getInjectionPoints() throws ConfigurationException {
return InjectionPoint.forInstanceMethodsAndFields(type);
}

/**
* Returns the looked up members injector. The result is not valid until this lookup has been
* initialized, which usually happens when the injector is created. The members injector will
@@ -107,4 +125,16 @@ public String toString() {
}
};
}

@Override
public boolean equals(Object obj) {
return obj instanceof MembersInjectorLookup
&& ((MembersInjectorLookup<?>) obj).type.equals(type)
&& ((MembersInjectorLookup<?>) obj).source.equals(source);
}

@Override
public int hashCode() {
return Objects.hashCode(type, source);
}
}
@@ -20,6 +20,7 @@
import static com.google.common.base.Preconditions.checkState;

import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Binder;
import com.google.inject.Key;
@@ -135,4 +136,16 @@ public String toString() {
.add("source", Errors.convert(source))
.toString();
}

@Override
public boolean equals(Object obj) {
return obj instanceof ProviderLookup
&& ((ProviderLookup<?>) obj).dependency.equals(dependency)
&& ((ProviderLookup<?>) obj).source.equals(source);
}

@Override
public int hashCode() {
return Objects.hashCode(dependency, source);
}
}
@@ -18,6 +18,7 @@

import static com.google.common.base.Preconditions.checkNotNull;

import com.google.common.base.Objects;
import com.google.inject.Binder;
import com.google.inject.ConfigurationException;
import java.util.Set;
@@ -76,4 +77,16 @@ public void applyTo(Binder binder) {
public <T> T acceptVisitor(ElementVisitor<T> visitor) {
return visitor.visit(this);
}

@Override
public boolean equals(Object obj) {
return obj instanceof StaticInjectionRequest
&& ((StaticInjectionRequest) obj).source.equals(source)
&& ((StaticInjectionRequest) obj).type.equals(type);
}

@Override
public int hashCode() {
return Objects.hashCode(source, type);
}
}
Oops, something went wrong.

0 comments on commit dafa4b0

Please sign in to comment.
You can’t perform that action at this time.