Annotation Processing @potatochips#43

A374f41eab3f73c50d8bab0652cb207a?s=47 TakuSemba
August 25, 2017

Annotation Processing @potatochips#43

A374f41eab3f73c50d8bab0652cb207a?s=128

TakuSemba

August 25, 2017
Tweet

Transcript

  1. Annotation Processing Taku Semba CyberAgent.Inc

  2. About Me Taku Semba TakuSemba @takusemba AbemaTV.Inc

  3. Annotation Processing Generate .java files when you compile

  4. Annotation Processing Generate .java files when you compile Merits

  5. Annotation Processing Generate .java files when you compile Merits ɾDo

    not need to write repeatedly
  6. Annotation Processing Generate .java files when you compile Merits ɾDo

    not need to write repeatedly ɾTrust the generated code
  7. Annotation Processing Generate .java files when you compile Merits Components

    ɾDo not need to write repeatedly ɾTrust the generated code
  8. Annotation Processing Generate .java files when you compile Merits Components

    ɾDo not need to write repeatedly ɾTrust the generated code ɾAnnotation
  9. Annotation Processing Generate .java files when you compile Merits Components

    ɾDo not need to write repeatedly ɾTrust the generated code ɾAnnotation ɾProcessor
  10. class User { String name; int age; }

  11. public final class UserBuilder { private String name; private int

    age; public UserBuilder name(String name) { this.name = name; return this; } …. public User build() { User user = new User(); user.name = this.name; user.age = this.age; return target; } } class User { String name; int age; }
  12. class User { String name; int age; } User user

    = new UserBuilder() .age(23) .name("taku") .build();
  13. @Buildable class User { @BuilderField String name; @BuilderField int age;

    } User user = new UserBuilder() .age(23) .name("taku") .build();
  14. // BuildField.java @Target(ElementType.FIELD) @Retention(RetentionPolicy.SOURCE) public @interface BuilderField { } //

    Buildable.java @Target(ElementType.TYPE) @Retention(RetentionPolicy.SOURCE) public @interface Buildable { } Annotation
  15. Processor // BuilderProcessor.java @Override public synchronized void init(ProcessingEnvironment processingEnv) {

    // implementation } @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { // implementation }
  16. Processor // BuilderProcessor.java private Filer filer; private Messager messager; private

    Elements elements; @Override public synchronized void init(ProcessingEnvironment processingEnv) { super.init(processingEnv); this.messager = processingEnv.getMessager(); this.filer = processingEnv.getFiler(); this.elements = processingEnv.getElementUtils(); }
  17. Processor // BuilderProcessor.java @Override public boolean process(Set<? extends TypeElement> annotations,

    RoundEnvironment roundEnv) { // implementation }
  18. Javapoet

  19. Processor FieldSpec fieldSpec = FieldSpec .builder(String.class, ”name”, Modifier.PRIVATE) .build(); private

    String name;
  20. Processor MethodSpec methodSpec = MethodSpec .methodBuilder(”name”) .addModifiers(Modifier.PUBLIC) .returns(User.class) .addParameter(String.class, ”name”)

    .addStatement("this.$N = $N", ”name”, ”name”) .addStatement("return this") .build(); public UserBuilder name(String name) { this.name = name; return this; }
  21. Processor TypeSpec classSpec = TypeSpec .classBuilder(”UserBuilder”) .addModifiers(Modifier.PUBLIC, Modifier.FINAL) .addFields(fieldSpecs) .addMethods(methodsSpecs)

    .build(); public final class UserBuilder { // fields and methods }
  22. Processor JavaFile file = JavaFile .builder(builderClass.packageName(), classSpec) .build(); try {

    file.writeTo(filer); } catch (IOException e) { messager.printMessage(Diagnostic.Kind.ERROR, "Failed to create file " + builderClass.packageName()); } > app/build/generated/source/apt/debug/your/package/UserBuilder.java
  23. @Buildable class User { @BuilderField String name; @BuilderField int age;

    }
  24. @Buildable class User { @BuilderField String name; @BuilderField int age;

    } public final class UserBuilder { private String name; private int age; …. public User build() { User user = new User(); user.name = this.name; user.age = this.age; return target; } }
  25. @Buildable class User { @BuilderField String name; @BuilderField int age;

    } public final class UserBuilder { private String name; private int age; …. public User build() { User user = new User(); user.name = this.name; user.age = this.age; return target; } } User user = new UserBuilder().age(23).name("taku").build();
  26. Sample Code https://github.com/TakuSemba/AutoBuilder

  27. Annotation Processing https://github.com/takusemba https://twitter.com/takusemba