Slide 1

Slide 1 text

Annotation Processing Taku Semba CyberAgent.Inc

Slide 2

Slide 2 text

About Me Taku Semba TakuSemba @takusemba AbemaTV.Inc

Slide 3

Slide 3 text

Annotation Processing Generate .java files when you compile

Slide 4

Slide 4 text

Annotation Processing Generate .java files when you compile Merits

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

class User { String name; int age; }

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

class User { String name; int age; } User user = new UserBuilder() .age(23) .name("taku") .build();

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

// BuildField.java @Target(ElementType.FIELD) @Retention(RetentionPolicy.SOURCE) public @interface BuilderField { } // Buildable.java @Target(ElementType.TYPE) @Retention(RetentionPolicy.SOURCE) public @interface Buildable { } Annotation

Slide 15

Slide 15 text

Processor // BuilderProcessor.java @Override public synchronized void init(ProcessingEnvironment processingEnv) { // implementation } @Override public boolean process(Set extends TypeElement> annotations, RoundEnvironment roundEnv) { // implementation }

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

Processor // BuilderProcessor.java @Override public boolean process(Set extends TypeElement> annotations, RoundEnvironment roundEnv) { // implementation }

Slide 18

Slide 18 text

Javapoet

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

Processor TypeSpec classSpec = TypeSpec .classBuilder(”UserBuilder”) .addModifiers(Modifier.PUBLIC, Modifier.FINAL) .addFields(fieldSpecs) .addMethods(methodsSpecs) .build(); public final class UserBuilder { // fields and methods }

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

@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();

Slide 26

Slide 26 text

Sample Code https://github.com/TakuSemba/AutoBuilder

Slide 27

Slide 27 text

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