0

The purpose of the project I'm working on is to handle annotation at compile time, it is not focused on what exactly I'm developing.

I took a simple subject for this and I'm writing a custom collection that will store elements and provide methods to manage them.

What I wanna do is to create an annotation @Contains, for example, to generate itemsContains method that could be processed while coding (instead of writing code manually).

public class Array {

    private List<String> items;

    public Array() {
        items = Arrays.asList("abc", "def", "xyz");
    }

    public boolean itemsContains(String expected) {
        return items.contains(expected);
    }
}

Generally, I want my class to look something like:

public class Array {

    @Contains
    private List<String> items;

    public Array() {
        items = Arrays.asList("abc", "def", "111");
    }
}

The important thing I want to reach is to have itemsContains method show up once the annotation is applied to a field. This is how it should look like:

expected result

Alternate existing examples are Lombok's @Getter/@Setter.

So what functionality or configurations should I implement to get the expected result? Would be grateful for some real implementations or guides how to perform it step by step.

Serhii Kachan
  • 345
  • 4
  • 13

1 Answers1

3

Annotation processing does not change the source file yet it generates a new file, Lombok on the other hand does a trick to modify the source file itself, meaning that you need to call the generated class somewhere in your code.

One way to do this is to generate a class that extends the main class

@Generated
public class ArrayProxy extends Array {
    public boolean itemsContains(String expected) {
        return items.contains(expected);
    }
}

and in your main class you need to do two things:

  • first you need to make items protected
  • you can add factory method to actually create the generated class
  public class Array {

   @Contains
   protected List<String> items;

   public static ArrayProxy create(){
       return new ArrayProxy();
   }

   private Array() {
       items = Arrays.asList("abc", "def", "111");
   }
}

And of course you need to use it like this

ArrayProxy array = Array.create();
array.itemsContains("expected");
rjeeb
  • 461
  • 3
  • 11
  • OK, that is the solution I haven't tried. But the actual question was how can we can change the AST of the source file during the compilation like Lombok does. I understand the process of compilation and it seems that the IDE compiler is controled by Lombok or what? Some resources say that there is a custom compiler needed. Am I right ? – Serhii Kachan Aug 15 '19 at 12:45