keys.add(Keys.get(field.getGenericType(), field.getAnnotations(), field)); provideKey = Keys.get(type); injectedConstructor.setAccessible(true); Type[] types = injectedConstructor.getGenericParameterTypes(); Annotation[][] annotations = injectedConstructor.getParameterAnnotations(); for (int p = 0; p < types.length; p++) { keys.add(Keys.get(types[p], annotations[p], injectedConstructor)); if (Keys.isPlatformType(supertype.getName())) { supertype = null; } else { keys.add(Keys.getMembersKey(supertype)); String membersKey = Keys.getMembersKey(type); return new ReflectiveAtInjectBinding<T>(provideKey, membersKey, singleton, type, injectedFields.toArray(new Field[injectedFields.size()]), injectedConstructor,
String builtInBindingsKey = Keys.getBuiltInBindingsKey(key); if (builtInBindingsKey != null) { return new BuiltInBinding<Object>(key, requiredBy, classLoader, builtInBindingsKey); String lazyKey = Keys.getLazyKey(key); if (lazyKey != null) { return new LazyBinding<Object>(key, requiredBy, classLoader, lazyKey); String className = Keys.getClassName(key); if (className == null) { throw new InvalidBindingException(key, + "in a @Provides method."); if (Keys.isAnnotated(key)) { throw new InvalidBindingException(key, "is a @Qualifier-annotated type and must be bound by a @Provides method.");
/** * Returns a key for {@code type} annotated with {@code annotations}, * wrapped by {@code Set}, reporting failures against {@code subject}. * * @param annotations the annotations on a single method, field or parameter. * This array may contain at most one qualifier annotation. */ public static String getSetKey(Type type, Annotation[] annotations, Object subject) { Annotation qualifier = extractQualifier(annotations, subject); type = boxIfPrimitive(type); StringBuilder result = new StringBuilder(); if (qualifier != null) { result.append(qualifier).append("/"); } result.append(SET_PREFIX); typeToString(type, result, true); result.append(">"); return result.toString(); }
/** * Returns a key for {@code type} annotated with {@code annotations}, * reporting failures against {@code subject}. * * @param annotations the annotations on a single method, field or parameter. * This array may contain at most one qualifier annotation. */ public static String get(Type type, Annotation[] annotations, Object subject) { return get(type, extractQualifier(annotations, subject)); }
/** * Returns a key for the underlying binding of a Lazy<T> value. For example, * if this is a key for a {@code Lazy<Foo>}, this returns the key for * {@code Foo}. This retains annotations. */ static String getLazyKey(String key) { int start = startOfType(key); if (substringStartsWith(key, start, LAZY_PREFIX)) { return extractKey(key, start, key.substring(0, start), LAZY_PREFIX); } else { return null; } }
/** Returns a key for {@code type} annotated by {@code annotation}. */ private static String get(Type type, Annotation annotation) { type = boxIfPrimitive(type); if (annotation == null && type instanceof Class && !((Class<?>) type).isArray()) { return ((Class<?>) type).getName(); } StringBuilder result = new StringBuilder(); if (annotation != null) { result.append(annotation).append("/"); } typeToString(type, result, true); return result.toString(); }
@Override public <T> T get(Class<T> type) { String key = Keys.get(type); String injectableTypeKey = type.isInterface() ? key : Keys.getMembersKey(type); ClassLoader classLoader = type.getClassLoader(); @SuppressWarnings("unchecked") // The linker matches keys to bindings by their type. Binding<T> binding = (Binding<T>) getInjectableTypeBinding(classLoader, injectableTypeKey, key); return binding.get(); }
/** Returns a key for {@code type} with no annotation. */ public static String get(Type type) { return get(type, null); }
protected Binding(String provideKey, String membersKey, boolean singleton, Object requiredBy) { if (singleton && provideKey == null) { throw new InvalidBindingException(Keys.getClassName(membersKey), "is exclusively members injected and therefore cannot be scoped"); } this.provideKey = provideKey; this.membersKey = membersKey; this.requiredBy = requiredBy; this.bits = (singleton ? SINGLETON : 0); }
/** * Returns the supertype, or {@code null} if the supertype is a platform * class. This is intended for annotation processors that assume platform * classes will never be annotated with application annotations. */ public static TypeMirror getApplicationSupertype(TypeElement type) { TypeMirror supertype = type.getSuperclass(); return Keys.isPlatformType(supertype.toString()) ? null : supertype; }
@Override public <T> T inject(T instance) { String membersKey = Keys.getMembersKey(instance.getClass()); ClassLoader classLoader = instance.getClass().getClassLoader(); @SuppressWarnings("unchecked") // The linker matches keys to bindings by their type. Binding<T> binding = (Binding<T>) getInjectableTypeBinding(classLoader, membersKey, membersKey); binding.injectMembers(instance); return instance; }
@Test public void testGetDelegateKeyWithMembersInjector() throws NoSuchFieldException { assertThat(Keys.getBuiltInBindingsKey(fieldKey("membersInjectorOfType"))) .isEqualTo("members/java.lang.String"); }
@Test public void testGetLazyKey_WrongKeyType() throws NoSuchFieldException { assertThat(Keys.getLazyKey(fieldKey("providerOfTypeAnnotated"))).isNull(); }
@Test public void testIsAnnotatedFalse() throws NoSuchFieldException { assertThat(Keys.isAnnotated(fieldKey("notAnnotated"))).isFalse(); }
/** * Returns a key for the type provided by, or injected by this key. For * example, if this is a key for a {@code Provider<Foo>}, this returns the * key for {@code Foo}. This retains annotations and supports both Provider * keys and MembersInjector keys. */ static String getBuiltInBindingsKey(String key) { int start = startOfType(key); if (substringStartsWith(key, start, PROVIDER_PREFIX)) { return extractKey(key, start, key.substring(0, start), PROVIDER_PREFIX); } else if (substringStartsWith(key, start, MEMBERS_INJECTOR_PREFIX)) { return extractKey(key, start, "members/", MEMBERS_INJECTOR_PREFIX); } else { return null; } }
private static String[] injectableTypesToKeys(Class<?>[] injectableTypes) { String[] result = new String[injectableTypes.length]; for (int i = 0; i < injectableTypes.length; i++) { Class<?> injectableType = injectableTypes[i]; result[i] = injectableType.isInterface() ? Keys.get(injectableType) : Keys.getMembersKey(injectableType); } return result; }
@Override public void attach(Linker linker) { bindings = new Binding<?>[fields.length]; for (int i = 0; i < fields.length; i++) { Field field = fields[i]; String key = Keys.get(field.getGenericType(), field.getAnnotations(), field); bindings[i] = linker.requestBinding(key, field, loader); } }
/** * Returns a key for {@code type} annotated with {@code annotations}, * reporting failures against {@code subject}. * * @param annotations the annotations on a single method, field or parameter. * This array may contain at most one qualifier annotation. */ public static String get(Type type, Annotation[] annotations, Object subject) { return get(type, extractQualifier(annotations, subject)); }
@Test public void testGetClassNameWithoutAnnotation() throws NoSuchFieldException { assertThat(Keys.getClassName(fieldKey("classNameWithAnnotation"))) .isEqualTo("java.lang.String"); }