spoon icon indicating copy to clipboard operation
spoon copied to clipboard

How can I add code to a constructor?

Open chaganiu opened this issue 4 years ago • 3 comments

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);
    }
}

chaganiu avatar Jan 26 '22 03:01 chaganiu

bump. can anyone help here?

chaganiu avatar Jan 28 '22 14:01 chaganiu

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 avatar Jan 28 '22 17:01 MartinWitt

@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.

chaganiu avatar Jan 31 '22 15:01 chaganiu