Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Annotation Processing @potatochips#43

TakuSemba
August 25, 2017

Annotation Processing @potatochips#43

TakuSemba

August 25, 2017
Tweet

More Decks by TakuSemba

Other Decks in Technology

Transcript

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

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

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

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

    ɾDo not need to write repeatedly ɾTrust the generated code ɾAnnotation ɾProcessor
  5. 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; }
  6. class User { String name; int age; } User user

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

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

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

    // implementation } @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { // implementation }
  10. 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(); }
  11. 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; }
  12. 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
  13. @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; } }
  14. @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();