/** * Adds an error if there is a misplaced annotations on {@code type}. * Scoping annotations are not allowed on abstract classes or interfaces. */ public static void checkForMisplacedScopeAnnotations(Class<?> type, Object source, Errors errors) { if (Classes.isConcrete(type)) { return; } Class<? extends Annotation> scopeAnnotation = findScopeAnnotation( errors, type); if (scopeAnnotation != null // We let Dagger Components through to aid migrations. && !containsComponentAnnotation(type.getAnnotations())) { errors.withSource(type).scopeAnnotationOnAbstractType( scopeAnnotation, type, source); } }
public void testOneMethodThatIsntGet() { try { Guice.createInjector( new AbstractModule() { @Override protected void configure() { install(ThrowingProviderBinder.forModule(this)); } @SuppressWarnings("unused") @CheckedProvides(OneNoneGetMethod.class) String foo() { return null; } }); fail(); } catch (CreationException ce) { assertEquals( OneNoneGetMethod.class.getName() + " may not declare any new methods, but declared " + Classes.toString(OneNoneGetMethod.class.getDeclaredMethods()[0]), Iterables.getOnlyElement(ce.getErrorMessages()).getMessage()); } }
private static void formatInjectionPoint( Formatter formatter, Dependency<?> dependency, InjectionPoint injectionPoint, ElementSource elementSource) { Member member = injectionPoint.getMember(); Class<? extends Member> memberType = Classes.memberType(member); if (memberType == Field.class) { dependency = injectionPoint.getDependencies().get(0); formatter.format(" while locating %s%n", convert(dependency.getKey(), elementSource)); formatter.format(" for field at %s%n", StackTraceElements.forMember(member)); } else if (dependency != null) { formatter.format(" while locating %s%n", convert(dependency.getKey(), elementSource)); formatter.format(" for %s%n", formatParameter(dependency)); } else { formatSource(formatter, injectionPoint.getMember()); } }
public void testOneMethodThatIsntGet() { try { Guice.createInjector(new AbstractModule() { @Override protected void configure() { install(ThrowingProviderBinder.forModule(this)); } @SuppressWarnings("unused") @CheckedProvides(OneNoneGetMethod.class) String foo() { return null; } }); fail(); } catch(CreationException ce) { assertEquals(OneNoneGetMethod.class.getName() + " may not declare any new methods, but declared " + Classes.toString(OneNoneGetMethod.class.getDeclaredMethods()[0]), Iterables.getOnlyElement(ce.getErrorMessages()).getMessage()); } }
public void testOneMethodThatIsntGet() { try { Guice.createInjector(new AbstractModule() { protected void configure() { install(ThrowingProviderBinder.forModule(this)); } @SuppressWarnings("unused") @CheckedProvides(OneNoneGetMethod.class) String foo() { return null; } }); fail(); } catch(CreationException ce) { assertEquals(OneNoneGetMethod.class.getName() + " may not declare any new methods, but declared " + Classes.toString(OneNoneGetMethod.class.getDeclaredMethods()[0]), Iterables.getOnlyElement(ce.getErrorMessages()).getMessage()); } }
public static void formatInjectionPoint(Formatter formatter, Dependency<?> dependency, InjectionPoint injectionPoint, ElementSource elementSource) { Member member = injectionPoint.getMember(); Class<? extends Member> memberType = Classes.memberType(member); if (memberType == Field.class) { dependency = injectionPoint.getDependencies().get(0); formatter.format(" while locating %s%n", convert(dependency.getKey(), elementSource)); formatter.format(" for field at %s%n", StackTraceElements.forMember(member)); } else if (dependency != null) { formatter.format(" while locating %s%n", convert(dependency.getKey(), elementSource)); formatter.format(" for parameter %s at %s%n", dependency.getParameterIndex(), StackTraceElements.forMember(member)); } else { formatSource(formatter, injectionPoint.getMember()); } }
public static void formatInjectionPoint(Formatter formatter, Dependency<?> dependency, InjectionPoint injectionPoint) { Member member = injectionPoint.getMember(); Class<? extends Member> memberType = Classes.memberType(member); if (memberType == Field.class) { dependency = injectionPoint.getDependencies().get(0); formatter.format(" while locating %s%n", convert(dependency.getKey())); formatter.format(" for field at %s%n", StackTraceElements.forMember(member)); } else if (dependency != null) { formatter.format(" while locating %s%n", convert(dependency.getKey())); formatter.format(" for parameter %s at %s%n", dependency.getParameterIndex(), StackTraceElements.forMember(member)); } else { formatSource(formatter, injectionPoint.getMember()); } }
/** * Adds an error if there is a misplaced annotations on {@code type}. Scoping annotations are not * allowed on abstract classes or interfaces. */ public static void checkForMisplacedScopeAnnotations( Class<?> type, Object source, Errors errors) { if (Classes.isConcrete(type)) { return; } Class<? extends Annotation> scopeAnnotation = findScopeAnnotation(errors, type); if (scopeAnnotation != null // We let Dagger Components through to aid migrations. && !containsComponentAnnotation(type.getAnnotations())) { errors.withSource(type).scopeAnnotationOnAbstractType(scopeAnnotation, type, source); } }
/** * Adds an error if there is a misplaced annotations on {@code type}. Scoping * annotations are not allowed on abstract classes or interfaces. */ public static void checkForMisplacedScopeAnnotations( Class<?> type, Object source, Errors errors) { if (Classes.isConcrete(type)) { return; } Class<? extends Annotation> scopeAnnotation = findScopeAnnotation(errors, type); if (scopeAnnotation != null) { errors.withSource(type).scopeAnnotationOnAbstractType(scopeAnnotation, type, source); } }
@Override public String toString(Member member) { return Classes.toString(member); }
/** * Finds a constructor suitable for the method. If the implementation contained any constructors * marked with {@link AssistedInject}, this requires all {@link Assisted} parameters to exactly * match the parameters (in any order) listed in the method. Otherwise, if no {@link * AssistedInject} constructors exist, this will default to looking for an {@literal @}{@link * Inject} constructor. */ private <T> InjectionPoint findMatchingConstructorInjectionPoint( Method method, Key<?> returnType, TypeLiteral<T> implementation, List<Key<?>> paramList) throws ErrorsException { Errors errors = new Errors(method); if (returnType.getTypeLiteral().equals(implementation)) { errors = errors.withSource(implementation); } else { errors = errors.withSource(returnType).withSource(implementation); } Class<?> rawType = implementation.getRawType(); if (Modifier.isInterface(rawType.getModifiers())) { errors.addMessage( "%s is an interface, not a concrete class. Unable to create AssistedInject factory.", implementation); throw errors.toException(); } else if (Modifier.isAbstract(rawType.getModifiers())) { errors.addMessage( "%s is abstract, not a concrete class. Unable to create AssistedInject factory.", implementation); throw errors.toException(); } else if (Classes.isInnerClass(rawType)) { errors.cannotInjectInnerClass(rawType); throw errors.toException(); } Constructor<?> matchingConstructor = null; boolean anyAssistedInjectConstructors = false; // Look for AssistedInject constructors... for (Constructor<?> constructor : rawType.getDeclaredConstructors()) { if (constructor.isAnnotationPresent(AssistedInject.class)) { anyAssistedInjectConstructors = true; if (constructorHasMatchingParams(implementation, constructor, paramList, errors)) { if (matchingConstructor != null) { errors.addMessage( "%s has more than one constructor annotated with @AssistedInject" + " that matches the parameters in method %s. Unable to create " + "AssistedInject factory.", implementation, method); throw errors.toException(); } else { matchingConstructor = constructor; } } } } if (!anyAssistedInjectConstructors) { // If none existed, use @Inject. try { return InjectionPoint.forConstructorOf(implementation); } catch (ConfigurationException e) { errors.merge(e.getErrorMessages()); throw errors.toException(); } } else { // Otherwise, use it or fail with a good error message. if (matchingConstructor != null) { // safe because we got the constructor from this implementation. @SuppressWarnings("unchecked") InjectionPoint ip = InjectionPoint.forConstructor( (Constructor<? super T>) matchingConstructor, implementation); return ip; } else { errors.addMessage( "%s has @AssistedInject constructors, but none of them match the" + " parameters in method %s. Unable to create AssistedInject factory.", implementation, method); throw errors.toException(); } } }
@Override public String toString() { return Classes.toString(member); }
/** * @param constructorInjector the constructor to use, or {@code null} to use the default. * @param failIfNotLinked true if this ConstructorBindingImpl's InternalFactory should only * succeed if retrieved from a linked binding */ static <T> ConstructorBindingImpl<T> create( InjectorImpl injector, Key<T> key, InjectionPoint constructorInjector, Object source, Scoping scoping, Errors errors, boolean failIfNotLinked, boolean failIfNotExplicit) throws ErrorsException { int numErrors = errors.size(); @SuppressWarnings("unchecked") // constructorBinding guarantees type is consistent Class<? super T> rawType = constructorInjector == null ? key.getTypeLiteral().getRawType() : (Class) constructorInjector.getDeclaringType().getRawType(); // We can't inject abstract classes. if (Modifier.isAbstract(rawType.getModifiers())) { errors.missingImplementationWithHint(key, injector); } // Error: Inner class. if (Classes.isInnerClass(rawType)) { errors.cannotInjectInnerClass(rawType); } errors.throwIfNewErrors(numErrors); // Find a constructor annotated @Inject if (constructorInjector == null) { try { constructorInjector = InjectionPoint.forConstructorOf(key.getTypeLiteral()); if (failIfNotExplicit && !hasAtInject((Constructor) constructorInjector.getMember())) { errors.atInjectRequired(rawType); } } catch (ConfigurationException e) { throw errors.merge(e.getErrorMessages()).toException(); } } // if no scope is specified, look for a scoping annotation on the concrete class if (!scoping.isExplicitlyScoped()) { Class<?> annotatedType = constructorInjector.getMember().getDeclaringClass(); Class<? extends Annotation> scopeAnnotation = findScopeAnnotation(errors, annotatedType); if (scopeAnnotation != null) { scoping = Scoping.makeInjectable( Scoping.forAnnotation(scopeAnnotation), injector, errors.withSource(rawType)); } } errors.throwIfNewErrors(numErrors); Factory<T> factoryFactory = new Factory<>(failIfNotLinked, key); InternalFactory<? extends T> scopedFactory = Scoping.scope(key, injector, factoryFactory, source, scoping); return new ConstructorBindingImpl<T>( injector, key, source, scopedFactory, scoping, factoryFactory, constructorInjector); }
/** * Finds a constructor suitable for the method. If the implementation contained any constructors * marked with {@link AssistedInject}, this requires all {@link Assisted} parameters to exactly * match the parameters (in any order) listed in the method. Otherwise, if no * {@link AssistedInject} constructors exist, this will default to looking for an * {@literal @}{@link Inject} constructor. */ private InjectionPoint findMatchingConstructorInjectionPoint( Method method, Key<?> returnType, TypeLiteral<?> implementation, List<Key<?>> paramList) throws ErrorsException { Errors errors = new Errors(method); if(returnType.getTypeLiteral().equals(implementation)) { errors = errors.withSource(implementation); } else { errors = errors.withSource(returnType).withSource(implementation); } Class<?> rawType = implementation.getRawType(); if (Modifier.isInterface(rawType.getModifiers())) { errors.addMessage( "%s is an interface, not a concrete class. Unable to create AssistedInject factory.", implementation); throw errors.toException(); } else if (Modifier.isAbstract(rawType.getModifiers())) { errors.addMessage( "%s is abstract, not a concrete class. Unable to create AssistedInject factory.", implementation); throw errors.toException(); } else if (Classes.isInnerClass(rawType)) { errors.cannotInjectInnerClass(rawType); throw errors.toException(); } Constructor<?> matchingConstructor = null; boolean anyAssistedInjectConstructors = false; // Look for AssistedInject constructors... for (Constructor<?> constructor : rawType.getDeclaredConstructors()) { if (constructor.isAnnotationPresent(AssistedInject.class)) { anyAssistedInjectConstructors = true; if (constructorHasMatchingParams(implementation, constructor, paramList, errors)) { if (matchingConstructor != null) { errors .addMessage( "%s has more than one constructor annotated with @AssistedInject" + " that matches the parameters in method %s. Unable to create AssistedInject factory.", implementation, method); throw errors.toException(); } else { matchingConstructor = constructor; } } } } if(!anyAssistedInjectConstructors) { // If none existed, use @Inject. try { return InjectionPoint.forConstructorOf(implementation); } catch(ConfigurationException e) { errors.merge(e.getErrorMessages()); throw errors.toException(); } } else { // Otherwise, use it or fail with a good error message. if(matchingConstructor != null) { // safe because we got the constructor from this implementation. @SuppressWarnings("unchecked") InjectionPoint ip = InjectionPoint.forConstructor( (Constructor)matchingConstructor, implementation); return ip; } else { errors.addMessage( "%s has @AssistedInject constructors, but none of them match the" + " parameters in method %s. Unable to create AssistedInject factory.", implementation, method); throw errors.toException(); } } }
/** * @param constructorInjector the constructor to use, or {@code null} to use the default. * @param failIfNotLinked true if this ConstructorBindingImpl's InternalFactory should * only succeed if retrieved from a linked binding */ static <T> ConstructorBindingImpl<T> create(InjectorImpl injector, Key<T> key, InjectionPoint constructorInjector, Object source, Scoping scoping, Errors errors, boolean failIfNotLinked, boolean failIfNotExplicit) throws ErrorsException { int numErrors = errors.size(); @SuppressWarnings("unchecked") // constructorBinding guarantees type is consistent Class<? super T> rawType = constructorInjector == null ? key.getTypeLiteral().getRawType() : (Class) constructorInjector.getDeclaringType().getRawType(); // We can't inject abstract classes. if (Modifier.isAbstract(rawType.getModifiers())) { errors.missingImplementation(key); } // Error: Inner class. if (Classes.isInnerClass(rawType)) { errors.cannotInjectInnerClass(rawType); } errors.throwIfNewErrors(numErrors); // Find a constructor annotated @Inject if (constructorInjector == null) { try { constructorInjector = InjectionPoint.forConstructorOf(key.getTypeLiteral()); if (failIfNotExplicit && !hasAtInject((Constructor) constructorInjector.getMember())) { errors.atInjectRequired(rawType); } } catch (ConfigurationException e) { throw errors.merge(e.getErrorMessages()).toException(); } } // if no scope is specified, look for a scoping annotation on the concrete class if (!scoping.isExplicitlyScoped()) { Class<?> annotatedType = constructorInjector.getMember().getDeclaringClass(); Class<? extends Annotation> scopeAnnotation = findScopeAnnotation(errors, annotatedType); if (scopeAnnotation != null) { scoping = Scoping.makeInjectable(Scoping.forAnnotation(scopeAnnotation), injector, errors.withSource(rawType)); } } errors.throwIfNewErrors(numErrors); Factory<T> factoryFactory = new Factory<T>(failIfNotLinked, key); InternalFactory<? extends T> scopedFactory = Scoping.scope(key, injector, factoryFactory, source, scoping); return new ConstructorBindingImpl<T>( injector, key, source, scopedFactory, scoping, factoryFactory, constructorInjector); }