How can I add code to a constructor?
I'm having trouble adding code to a constructor. I was able to get some of the examples working in the example repo but couldn't figure out how to get this to work. What I want to do is:
For every @Find annotation I want to initialize the field inside the constructor that takes a parameter of type MyObject. The processor runs fine but the output is not there. nothing is outputed and no errors either.
My class:
public class SomeClass extends SomeBaseClass {
@Find(foo = "bar")
SomeInterface x;
public SomeClass(MyObject obj) {
super(obj);
// I want to add initialization code here
}
}
And here is my processor:
public class FindProcessor extends AbstractAnnotationProcessor<Find, CtAnnotation<?>> {
@Override
public void process(Find annotation, CtAnnotation<?> element) {
// get variable name of the field that is annotated
var variableName = element.getParent(CtField.class).getSimpleName();
// create a snippet that initializes the field
CtCodeSnippetStatement snippet = getFactory().Core().createCodeSnippetStatement();
final String value = String.format("%s = MyFactory.create('%s')", variableName, annotation.foo());
snippet.setValue(value);
// get the class that the field is in
var parentClass = element.getParent(CtClass.class);
// maybe this is the problem?
// Not sure how else to get CtTypeReference to pass to getConstructor
var constructorParamType = parentClass.getReferencedTypes()
.stream()
.filter(x -> x.getQualifiedName().equals("com.myPackage.foo.MyObject"))
.findFirst()
.orElse(null);
// get the constructor that has a parameter of type com.myPackage.foo.MyObject
var constructor = parentClass.getConstructor(constructorParamType);
// add the snipped at the end of the constructor
constructor.getBody().insertEnd(snippet);
}
}
bump. can anyone help here?
Can you show the code you use to invoke the processor? Your code should look something like this.
Launcher launcher = new Launcher();
launcher.addInputResource("... Path to Source ");
launcher.addProcessor(your Processor);
launcher.run();
@MartinWitt I am using the maven plugin:
<build>
<plugins>
<plugin>
<groupId>fr.inria.gforge.spoon</groupId>
<artifactId>spoon-maven-plugin</artifactId>
<version>3.5</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<processors>
<processor>
com.my.package.processors.FindProcessor
</processor>
</processors>
<debug>true</debug>
</configuration>
<dependencies>
<dependency>
<groupId>com.my.package</groupId>
<artifactId>annotation-processor</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
I know this works because I used this same thing with one of the samples and was able to see the output. I replaced my code with the code in one of the sample processors and was able to see the correct output so i'm fairly certain i have everything wired up correctly. but the code that i'm using above seems incorrect.