/** * Gets type literal from super class's type parameter. */ static TypeLiteral<?> fromSuperclassTypeParameter(Class<?> subclass) { return new TypeLiteral<Object>(getSuperclassTypeParameter(subclass)); }
@Override public final boolean equals(Object o) { if (o == this) { return true; } if (!(o instanceof Key<?>)) { return false; } Key<?> other = (Key<?>) o; return annotationStrategy.equals(other.annotationStrategy) && typeLiteral.equals(other.typeLiteral); }
/** * Resolves known type parameters in {@code toResolve} and returns the result. */ TypeLiteral<?> resolve(Type toResolve) { return TypeLiteral.get(resolveType(toResolve)); }
private static <M extends Member & AnnotatedElement> void addInjectionPoints(TypeLiteral<?> type, Factory<M> factory, boolean statics, Collection<InjectionPoint> injectionPoints, Errors errors) { if (type.getType() == Object.class) { return; } // Add injectors for superclass first. TypeLiteral<?> superType = type.getSupertype(type.getRawType().getSuperclass()); addInjectionPoints(superType, factory, statics, injectionPoints, errors); // Add injectors for all members next addInjectorsForMembers(type, factory, statics, injectionPoints, errors); }
<T> ProviderMethod<T> createProviderMethod(Binder binder, final Method method) { binder = binder.withSource(method); Errors errors = new Errors(method); // prepare the parameter providers Set<Dependency<?>> dependencies = new HashSet<>(); List<Provider<?>> parameterProviders = new ArrayList<>(); List<TypeLiteral<?>> parameterTypes = typeLiteral.getParameterTypes(method); Annotation[][] parameterAnnotations = method.getParameterAnnotations(); for (int i = 0; i < parameterTypes.size(); i++) { Key<?> key = getKey(errors, parameterTypes.get(i), method, parameterAnnotations[i]); dependencies.add(Dependency.get(key)); parameterProviders.add(binder.getProvider(key)); } @SuppressWarnings("unchecked") // Define T as the method's return type. TypeLiteral<T> returnType = (TypeLiteral<T>) typeLiteral.getReturnType(method); Key<T> key = getKey(errors, returnType, method, method.getAnnotations()); Class<? extends Annotation> scopeAnnotation = Annotations.findScopeAnnotation(errors, method.getAnnotations()); for (Message message : errors.getMessages()) { binder.addError(message); } return new ProviderMethod<>(key, method, delegate, unmodifiableSet(dependencies), parameterProviders, scopeAnnotation); }
/** * Constructs a new key. Derives the type from this class's type parameter. * <p> * Clients create an empty anonymous subclass. Doing so embeds the type * parameter in the anonymous class's type hierarchy so we can reconstitute it * at runtime despite erasure. * <p> * Example usage for a binding of type {@code Foo}: * <p> * {@code new Key<Foo>() {}}. */ @SuppressWarnings("unchecked") protected Key() { this.annotationStrategy = NullAnnotationStrategy.INSTANCE; this.typeLiteral = (TypeLiteral<T>) TypeLiteral.fromSuperclassTypeParameter(getClass()); this.hashCode = computeHashCode(); }
@Override public boolean matches(TypeLiteral<?> typeLiteral) { return typeLiteral.getRawType() == Class.class; }
@Override public boolean matches(TypeLiteral<?> typeLiteral) { Type type = typeLiteral.getType(); if (!(type instanceof Class)) { return false; } Class<?> clazz = (Class<?>) type; return typeMatcher.matches(clazz); }
List<AssistedConstructor<?>> constructors = new ArrayList<>(); for (Constructor<?> constructor : implementationType.getRawType().getDeclaredConstructors()) { if (constructor.getAnnotation(AssistedInject.class) != null) { @SuppressWarnings("unchecked") // the constructor type and implementation type agree AssistedConstructor assistedConstructor = new AssistedConstructor( constructor, implementationType.getParameterTypes(constructor)); constructors.add(assistedConstructor); Method[] factoryMethods = factoryType.getRawType().getMethods(); if (!method.getReturnType().isAssignableFrom(implementationType.getRawType())) { throw newConfigurationException("Return type of method %s is not assignable from %s", method, implementationType); for (TypeLiteral<?> parameterType : factoryType.getParameterTypes(method)) { parameterTypes.add(parameterType.getType());
/** * Gets type literal for the given {@code Class} instance. */ public static <T> TypeLiteral<T> get(Class<T> type) { return new TypeLiteral<>(type); }
Class<F> factoryRawType = (Class) factoryType.getRawType(); factoryType.getReturnType(method), method, method.getAnnotations(), errors); returnTypesBuilder.put(method, returnType); List<TypeLiteral<?>> params = factoryType.getParameterTypes(method); Annotation[][] paramAnnotations = method.getParameterAnnotations(); int p = 0;
/** * Returns a new mapbinder that collects entries of {@code keyType}/{@code valueType} in a * {@link Map} that is itself bound with {@code annotation}. */ public static <K, V> MapBinder<K, V> newMapBinder(Binder binder, Class<K> keyType, Class<V> valueType, Annotation annotation) { return newMapBinder(binder, TypeLiteral.get(keyType), TypeLiteral.get(valueType), annotation); }
/** * Constructs a new type literal. Derives represented class from type * parameter. * <p> * Clients create an empty anonymous subclass. Doing so embeds the type * parameter in the anonymous class's type hierarchy so we can reconstitute it * at runtime despite erasure. */ @SuppressWarnings("unchecked") protected TypeLiteral() { this.type = getSuperclassTypeParameter(getClass()); this.rawType = (Class<? super T>) MoreTypes.getRawType(type); this.hashCode = MoreTypes.hashCode(type); }
InjectionPoint(TypeLiteral<?> type, Field field) { this.member = field; Inject inject = field.getAnnotation(Inject.class); this.optional = inject.optional(); Annotation[] annotations = field.getAnnotations(); Errors errors = new Errors(field); Key<?> key = null; try { key = Annotations.getKey(type.getFieldType(field), field, annotations, errors); } catch (ErrorsException e) { errors.merge(e.getErrors()); } errors.throwConfigurationExceptionIfErrorsExist(); this.dependencies = Collections.<Dependency<?>>singletonList( newDependency(key, Nullability.allowsNull(annotations), -1)); }
private List<Dependency<?>> forMember(Member member, TypeLiteral<?> type, Annotation[][] parameterAnnotations) { Errors errors = new Errors(member); Iterator<Annotation[]> annotationsIterator = Arrays.asList(parameterAnnotations).iterator(); List<Dependency<?>> dependencies = new ArrayList<>(); int index = 0; for (TypeLiteral<?> parameterType : type.getParameterTypes(member)) { try { Annotation[] paramAnnotations = annotationsIterator.next(); Key<?> key = Annotations.getKey(parameterType, member, paramAnnotations, errors); dependencies.add(newDependency(key, Nullability.allowsNull(paramAnnotations), index)); index++; } catch (ErrorsException e) { errors.merge(e.getErrors()); } } errors.throwConfigurationExceptionIfErrorsExist(); return Collections.unmodifiableList(dependencies); }
private static <M extends Member & AnnotatedElement> void addInjectionPoints(TypeLiteral<?> type, Factory<M> factory, boolean statics, Collection<InjectionPoint> injectionPoints, Errors errors) { if (type.getType() == Object.class) { return; } // Add injectors for superclass first. TypeLiteral<?> superType = type.getSupertype(type.getRawType().getSuperclass()); addInjectionPoints(superType, factory, statics, injectionPoints, errors); // Add injectors for all members next addInjectorsForMembers(type, factory, statics, injectionPoints, errors); }
<T> ProviderMethod<T> createProviderMethod(Binder binder, final Method method) { binder = binder.withSource(method); Errors errors = new Errors(method); // prepare the parameter providers Set<Dependency<?>> dependencies = new HashSet<>(); List<Provider<?>> parameterProviders = new ArrayList<>(); List<TypeLiteral<?>> parameterTypes = typeLiteral.getParameterTypes(method); Annotation[][] parameterAnnotations = method.getParameterAnnotations(); for (int i = 0; i < parameterTypes.size(); i++) { Key<?> key = getKey(errors, parameterTypes.get(i), method, parameterAnnotations[i]); dependencies.add(Dependency.get(key)); parameterProviders.add(binder.getProvider(key)); } @SuppressWarnings("unchecked") // Define T as the method's return type. TypeLiteral<T> returnType = (TypeLiteral<T>) typeLiteral.getReturnType(method); Key<T> key = getKey(errors, returnType, method, method.getAnnotations()); Class<? extends Annotation> scopeAnnotation = Annotations.findScopeAnnotation(errors, method.getAnnotations()); for (Message message : errors.getMessages()) { binder.addError(message); } return new ProviderMethod<>(key, method, delegate, unmodifiableSet(dependencies), parameterProviders, scopeAnnotation); }
/** * Constructs a new key. Derives the type from this class's type parameter. * <p> * Clients create an empty anonymous subclass. Doing so embeds the type * parameter in the anonymous class's type hierarchy so we can reconstitute it * at runtime despite erasure. * <p> * Example usage for a binding of type {@code Foo} annotated with * {@code @Bar}: * <p> * {@code new Key<Foo>(new Bar()) {}}. */ @SuppressWarnings("unchecked") protected Key(Annotation annotation) { // no usages, not test-covered this.annotationStrategy = strategyFor(annotation); this.typeLiteral = (TypeLiteral<T>) TypeLiteral.fromSuperclassTypeParameter(getClass()); this.hashCode = computeHashCode(); }
Class<? super T> getRawType() { return typeLiteral.getRawType(); }