Reputation: 2656
@GenerateInterface class A {}
@GenerateInterface class B {
void setA(IA a) {}
}
My annotation processor should generate these interfaces:
interface IA {}
interface IB {
void setA(IA a);
}
B
compiles fine with correct import statement. IB
however, misses the parameter IA a
. I use javapoet to generate the interfaces. Code for compying the method parameters:
method.getParameters().forEach(p -> {
ParameterSpec.Builder parameterBuilder = ParameterSpec.builder(
TypeName.get(p.asType()),
p.getSimpleName().toString(),
p.getModifiers().toArray(new Modifier[p.getModifiers().size()]));
p.getAnnotationMirrors().stream()
.map(AnnotationSpec::get)
.forEach(parameterBuilder::addAnnotation);
methodBuilder.addParameter(parameterBuilder.build());
});
method
is an ExecutableElement
. p.asType()
only holds the simple name IA
. At this point, IA
has possibly not been generated yet, so no fully qualified name is available.
At the moment I generate interfaces one by one for each annotated class. As far as I understand I first of all need a list of all annotated classes and their derived interface names. Then when I encounter a parameter that is of a yet to be generated type, get the fully qualified name from the list above to insert a correct import statement.
Is there a smart way to do this? Can I at least distinguish yet to be compiled types from already compiled ones?
Edit: full code
Upvotes: 2
Views: 421
Reputation: 4838
I'm working on an Annotation Processor for my Kripton Persistence Library and I have a similar problem. My problem is similar but not the same: in my generated classes I referer other generated classes that are generated in the same round.
The solution that I apply is simply "generate" the TypeName by hand. In my Annotation Processor, I use a specific class, which source you can found here.
Kripton will generate classes that implement SQLite-based DAO pattern for Android platform. When I generated my DataSource, I need to referer the DAO classes that will be generated in the same round. To do this and avoid the same your problem, I generate the associated TypeName. You can see that on method buildDataSource
of the class BindDataSourceBuilder.
Hope that information is still useful for you.
Upvotes: 2