I'm trying to create an annotation processor which will process my MVP views (fragments) to auto-generated Subcomponents (similar to https://github.com/lukaspili/Auto-Dagger2, but for the new Dagger 2.10 android injectors)
So far, I've been able to generate appropriate files, but there is a strange error message when compiling generated components
Error:(22, 58) error: @dagger.android.support.FragmentKey methods should bind dagger.android.AndroidInjector.Factory<? extends android.support.v4.app.Fragment>, not dagger.android.AndroidInjector.Factory<? extends android.support.v4.app.Fragment>. See google.github.io/dagger/android
The structure of Factory module and Subcomponent files should be correct, because as soon as I copy-paste the generated classes and create a regular classes (both Factory module and Subcomponent) and use real classes instead of generated ones, the message is no longer shown and compilation succeeds
It seems like the problem lies in AndroidMapKeyValidator
(link), where !MoreTypes.equivalence().equivalent(returnType, intendedReturnType)
call apparently fails, but I don't have much of an experience debugging annotation processors, so I don't know why precisely...
Can maybe anyone help where to search for the problem? Thanks
FYI: MyFragment
does extend android.support.v4.app.Fragment
Generated Factory
@Module
public interface BuildersModule {
@Binds
@IntoMap
@FragmentKey(MyFragment.class)
abstract AndroidInjector.Factory<? extends Fragment> factory(MySubcomponent.Builder builder);
}
Generated subcomponent
@Subcomponent(modules = MyModule.class)
public interface MySubcomponent extends AndroidInjector<MyFragment> {
MyPresenter presenter();
@Subcomponent.Builder
abstract class Builder extends AndroidInjector.Builder<MyFragment> {}
}
If anyone is interested in solution:
I found out that for some reason, references of ClassType
-s compared during project's compile time are not the same when validating generated method.
And these references, despite the fact that they are pointing to the same class, are checked for equality in auto-common
library in EqualVisitor.visitDeclared
method. Apparently, this can be a bug in auto-common
, because Elements in visitDeclared
are compared by object reference, but not type reference.
So workaround here is to use local fixed copy of auto-common
library and exclude all dependencies of the original library.
//TODO think if this is the correct solution to cast both elements
//return aElement.equals(bElement)
return ((TypeElement) aElement).getQualifiedName().equals(((TypeElement) bElement).getQualifiedName())
&& equal(a.getEnclosingType(), b.getEnclosingType(), newVisiting)
&& equalLists(a.getTypeArguments(), b.getTypeArguments(), newVisiting);
auto-common
(I use just a quickfix) before filing an issue in auto-common
repo.