javamavenintellij-ideavavr

Vavr annotation procession tool doesn't kick-in


I am trying to replicate a simple Object Decomposition example from here. I've added the following dependencies to my project:

      <dependency>
        <groupId>io.vavr</groupId>
        <artifactId>vavr</artifactId>
        <version>${vavr.version}</version>
      </dependency>
      <dependency>
        <groupId>io.vavr</groupId>
        <artifactId>vavr-match</artifactId>
        <version>${vavr.version}</version>
      </dependency>
      <dependency>
        <groupId>io.vavr</groupId>
        <artifactId>vavr-match-processor</artifactId>
        <version>${vavr.version}</version>
      </dependency>

...where vavr.version is 0.10.3 and have copy-pasted the example from the above source:

import io.vavr.Tuple;
import io.vavr.Tuple2;
import io.vavr.match.annotation.Patterns;
import io.vavr.match.annotation.Unapply;
import lombok.AllArgsConstructor;
import lombok.Getter;

import static io.vavr.API.$;
import static io.vavr.API.Match;
import static io.vavr.API.Match.*;

public class Example {

  @Getter
  @AllArgsConstructor
  public static class Employee {
    private String name;
    private String id;
  }

  @Patterns
  public static class Demo {
    @Unapply
    static Tuple2<String, String> Employee(Employee Employee) {
      return Tuple.of(Employee.getName(), Employee.getId());
    }
  }

  public static void main(String[] args) {
    Employee person = new Employee("Carl", "89696D8");

    String result = Match(person).of(
      Case(Demo.Employee($("Carl"), $()), (name, id) -> ""),
      Case($(), () -> "notfound")
    );
  }
}

However the first Case yields a compile error Expected 1 argument but found 2 which suggests to me that the annotation processing didn't work and the corresponding pattern hasn't been generated. Correct me if I am wrong.

I am working with Intellij 2020.1 and have annotation processing enabled in it


Solution

  • The reason is that you have used invalid name of the generated class in this line:

    Case(Demo.Employee($("Carl"), $()), (name, id) -> "")
    

    It should be replaced with:

    Case(Example_DemoPatterns.$Employee($("Carl"), $()), (name, id) -> name + " " + id)
    

    since Demo is a static nested class it needs to be prefixed with Example_ and because this is how the generator works it needs to suffixed with Patterns.

    Here is a complete, buildable example that you can clone and try it out. It contains examples for both maven and gradle. To verify how it works change the mentioned line to e.g.:

    Case(Example_DemoPatternsWhatever.$Employee($("Carl"), $()), (name, id) -> name + " " + id)
    

    and then run:

    mvn exec:java
    

    It fails (there's no such class generated) but when you run tree target/ you will get something like:

    target
    ├── classes
    ├── generated-sources
    │   └── annotations
    │       └── Example_DemoPatterns.java
    └── maven-status
        └── maven-compiler-plugin
            └── compile
                └── default-compile
                    ├── createdFiles.lst
                    └── inputFiles.lst
    

    which means that the class was indeed generated. This is the class you need to use.