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

ぼくにもできた Annotation Processing

ぼくにもできた Annotation Processing

ぼくにもできた
Annotation Processing

Avatar for Fumihiko Shiroyama

Fumihiko Shiroyama

January 20, 2017
Tweet

More Decks by Fumihiko Shiroyama

Other Decks in Technology

Transcript

  1. ར༻ྫ " ੜ੒͞ΕͨίʔυΛͦͷ··ར༻͢ΔλΠϓ w "OESPJE"OOPUBUJPOT FUDʜ # ॲཧΛҕৡ͢ΔλΠϓ w #VUUFS,OJGF

    1FSNJTTJPOT%JTQBUDIFS FUDʜ Ҡৡͷίʔυ͕ෆཁ͕ͩ ར༻ଆͰੜ੒͞ΕͨίʔυΛҙࣝ͢Δඞཁ͕͋Δ .BOJGFTUʹొ࿥͕ඞཁ౳ Ҡৡͷίʔυ͕ඞཁ͕ͩ ݩΫϥε͸ͦͷ··ͰΑ͍
  2. MJCSBSZNPEVMF w +BWB-JCSBSZ"OESPJE-JCSBSZ w "OOPUBUJPOΫϥε΍ϥΠϒϥϦͱͯ͠ఏڙ͢Δ࣮ॲཧΛ ॻ͍ͨΫϥε͕ॴଐ w +BWB POMZ+BDL 

    w ίϯύΠϧ࣌ͷΈඞཁͳ৔߹͸QSPWJEFE w BQQϞδϡʔϧ͔ΒϥΠϒϥϦͷίʔυΛࢀর͢Δ৔߹ ͸DPNQJMF
  3. @MyCoolAnnotation
 public class SampleClass {
 @MyCoolAnnotation
 final String text;
 


    public SampleClass(String text) {
 this.text = text;
 }
 } TBNQMFNPEVMF
  4. QSPDFTTPSNPEVMF dependencies {
 compile project(":library")
 compile 'com.squareup:javapoet:1.8.0'
 compile 'com.google.auto.service:auto-service:1.0-rc2'
 compile

    'com.google.android:android:4.1.1.4'
 }
 sourceSets {
 main {
 java {
 srcDirs = [‘src/main/java', '../library/src/main/java']
 }
 }
 }
  5. QSPDFTTPSNPEVMF dependencies {
 compile project(":library")
 compile 'com.squareup:javapoet:1.8.0'
 compile 'com.google.auto.service:auto-service:1.0-rc2'
 compile

    'com.google.android:android:4.1.1.4'
 }
 sourceSets {
 main {
 java {
 srcDirs = [‘src/main/java', '../library/src/main/java']
 }
 }
 } BOESPJEMJCSBSZΛࢀর͢Δ৔߹ BOESPJEMJCSBSZΛࢀর͢Δ৔߹
  6. @AutoService(Processor.class)
 public class MyProcessor extends AbstractProcessor {
 @Override
 public Set<String>

    getSupportedAnnotationTypes() {
 return ImmutableSet.of(MyCoolAnnotation.class.getName());
 }
 
 @Override
 public SourceVersion getSupportedSourceVersion() {
 return SourceVersion.latest();
 }
 
 @Override
 public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
 return false;
 }
 } QSPDFTTPSNPEVMF
  7. @AutoService(Processor.class)
 public class MyProcessor extends AbstractProcessor {
 @Override
 public Set<String>

    getSupportedAnnotationTypes() {
 return ImmutableSet.of(MyCoolAnnotation.class.getName());
 }
 
 @Override
 public SourceVersion getSupportedSourceVersion() {
 return SourceVersion.latest();
 }
 
 @Override
 public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
 return false;
 }
 } QSPDFTTPSNPEVMF 1SPDFTTPS͸͜ͷந৅ΫϥεΛܧঝͯ͠ ࡞Δͷ͕ศར
  8. @AutoService(Processor.class)
 public class MyProcessor extends AbstractProcessor {
 @Override
 public Set<String>

    getSupportedAnnotationTypes() {
 return ImmutableSet.of(MyCoolAnnotation.class.getName());
 }
 
 @Override
 public SourceVersion getSupportedSourceVersion() {
 return SourceVersion.latest();
 }
 
 @Override
 public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
 return false;
 }
 } QSPDFTTPSNPEVMF ίϯύΠϧ࣌ʹ͜ͷ1SPDFTTPS͕࣮ߦ͞ΕΔ
  9. @AutoService(Processor.class)
 public class MyProcessor extends AbstractProcessor {
 @Override
 public Set<String>

    getSupportedAnnotationTypes() {
 return ImmutableSet.of(MyCoolAnnotation.class.getName());
 }
 
 @Override
 public SourceVersion getSupportedSourceVersion() {
 return SourceVersion.latest();
 }
 
 @Override
 public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
 return false;
 }
 } QSPDFTTPSNPEVMF ॲཧର৅ͷΞϊςʔγϣϯΛ4FUͰࢦఆ
  10. @AutoService(Processor.class)
 public class MyProcessor extends AbstractProcessor {
 @Override
 public Set<String>

    getSupportedAnnotationTypes() {
 return ImmutableSet.of(MyCoolAnnotation.class.getName());
 }
 
 @Override
 public SourceVersion getSupportedSourceVersion() {
 return SourceVersion.latest();
 }
 
 @Override
 public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
 return false;
 }
 } QSPDFTTPSNPEVMF αϙʔτ্ݶͷ+BWBόʔδϣϯ
  11. @AutoService(Processor.class)
 public class MyProcessor extends AbstractProcessor {
 @Override
 public Set<String>

    getSupportedAnnotationTypes() {
 return ImmutableSet.of(MyCoolAnnotation.class.getName());
 }
 
 @Override
 public SourceVersion getSupportedSourceVersion() {
 return SourceVersion.latest();
 }
 
 @Override
 public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
 return false;
 }
 } QSPDFTTPSNPEVMF ϓϩηοαʔʹΑΔॲཧຊମ
  12. QSPDFTTPSNPEVMF private Elements elementUtils;
 private Types typeUtils;
 private Messager messager;


    private Filer filer;
 
 @Override
 public synchronized void init(ProcessingEnvironment processingEnvironment) {
 super.init(processingEnvironment);
 
 elementUtils = processingEnvironment.getElementUtils();
 typeUtils = processingEnvironment.getTypeUtils();
 messager = processingEnvironment.getMessager();
 filer = processingEnvironment.getFiler();
 } ศརͳϢʔςΟϦςΟ܈
  13. QSPDFTTPSNPEVMF TypeElement classElement = roundEnvironment.getElementsAnnotatedWith(MyCoolAnnotation.class)
 .stream()
 .filter(element -> element.getKind() ==

    ElementKind.CLASS)
 .map(element -> (TypeElement) element)
 .findFirst()
 .get();
 
 String className = classElement.getSimpleName().toString();
 
 TypeSpec typeSpec = TypeSpec.classBuilder("Sub" + className).build();
 JavaFile javaFile = JavaFile.builder("com.example", typeSpec).build();
 try {
 javaFile.writeTo(filer);
 } catch (IOException e) {
 messager.printMessage(Diagnostic.Kind.ERROR, e.getMessage());
 } ΞϊςʔγϣϯʹରԠ͢Δཁૉ
  14. QSPDFTTPSNPEVMF TypeElement classElement = roundEnvironment.getElementsAnnotatedWith(MyCoolAnnotation.class)
 .stream()
 .filter(element -> element.getKind() ==

    ElementKind.CLASS)
 .map(element -> (TypeElement) element)
 .findFirst()
 .get();
 
 String className = classElement.getSimpleName().toString();
 
 TypeSpec typeSpec = TypeSpec.classBuilder("Sub" + className).build();
 JavaFile javaFile = JavaFile.builder("com.example", typeSpec).build();
 try {
 javaFile.writeTo(filer);
 } catch (IOException e) {
 messager.printMessage(Diagnostic.Kind.ERROR, e.getMessage());
 } ΫϥεΛऔಘ
  15. QSPDFTTPSNPEVMF TypeElement classElement = roundEnvironment.getElementsAnnotatedWith(MyCoolAnnotation.class)
 .stream()
 .filter(element -> element.getKind() ==

    ElementKind.CLASS)
 .map(element -> (TypeElement) element)
 .findFirst()
 .get();
 
 String className = classElement.getSimpleName().toString();
 
 TypeSpec typeSpec = TypeSpec.classBuilder("Sub" + className).build();
 JavaFile javaFile = JavaFile.builder("com.example", typeSpec).build();
 try {
 javaFile.writeTo(filer);
 } catch (IOException e) {
 messager.printMessage(Diagnostic.Kind.ERROR, e.getMessage());
 } +BWBΫϥεΛੜ੒
  16. public interface Greeter { String sayHello(); String sayHello(String toWhom); }

    public class EnglishGreeter implements Greeter { @Override public String sayHello() { return sayHello("ANONYMOUS"); } @Override public String sayHello(String toWhom) { return String.format("Hello %s !", toWhom); } } $VDLPP ΠϯλϑΣʔε
  17. public interface Greeter { String sayHello(); String sayHello(String toWhom); }

    public class EnglishGreeter implements Greeter { @Override public String sayHello() { return sayHello("ANONYMOUS"); } @Override public String sayHello(String toWhom) { return String.format("Hello %s !", toWhom); } } $VDLPP ࣮૷
  18. @Delegate public abstract class EnglishGreeterWithRecording implements Greeter { @By final

    EnglishGreeter englishGreeter = new EnglishGreeter(); @Override public String sayHello(String toWhom) { // do anything you like here return englishGreeter.sayHello(toWhom); } } $VDLPP
  19. @Delegate public abstract class EnglishGreeterWithRecording implements Greeter { @By final

    EnglishGreeter englishGreeter = new EnglishGreeter(); @Override public String sayHello(String toWhom) { // do anything you like here return englishGreeter.sayHello(toWhom); } } $VDLPP !"CTUSBDU !%FMFHBUF
  20. @Delegate public abstract class EnglishGreeterWithRecording implements Greeter { @By final

    EnglishGreeter englishGreeter = new EnglishGreeter(); @Override public String sayHello(String toWhom) { // do anything you like here return englishGreeter.sayHello(toWhom); } } $VDLPP JNQMFNFOUT
  21. @Delegate public abstract class EnglishGreeterWithRecording implements Greeter { @By final

    EnglishGreeter englishGreeter = new EnglishGreeter(); @Override public String sayHello(String toWhom) { // do anything you like here return englishGreeter.sayHello(toWhom); } } $VDLPP ੜ੒͞ΕͨΫϥε͸ ະ࣮૷ͷϝιου͸ !#Zम০ͨ͠Πϯελϯεʹ ͢΂ҕৡ͞ΕΔ
  22. $VDLPP OFX*OTUBODF Ͱऔಘ // in your code EnglishGreeterWithRecording greeter =

    EnglishGreeterWithRecordingImpl.newInstance(new EnglishGreeter());
  23. void fetchAsynchronously() { /* do heavy asynchronous task here */

    doCallback("finished!"); } void doCallback(@NonNull String message) { FinishDialog.newInstance().show(getSupportFragmentManager(), "TAG"); } 7VMUVSF
  24. void fetchAsynchronously() { /* do heavy asynchronous task here */

    doCallback("finished!"); } void doCallback(@NonNull String message) { FinishDialog.newInstance().show(getSupportFragmentManager(), "TAG"); } 7VMUVSF ඇಉظॲཧ
  25. void fetchAsynchronously() { /* do heavy asynchronous task here */

    doCallback("finished!"); } void doCallback(@NonNull String message) { FinishDialog.newInstance().show(getSupportFragmentManager(), "TAG"); } 7VMUVSF ίʔϧόοΫ PO1BVTFҎ߱͸Ϋϥογϡ
  26. 7VMUVSF @ObserveLifecycle public class YourActivity extends AppCompatActivity { void fetchAsynchronously()

    { SafeMainActivity.doCallbackSafely("finished!"); } @SafeCallback void doCallback(@NonNull String message) { FinishDialog.newInstance().show(getSupportFragmentManager(), "TAG"); } }
  27. 7VMUVSF @ObserveLifecycle public class YourActivity extends AppCompatActivity { void fetchAsynchronously()

    { SafeMainActivity.doCallbackSafely("finished!"); } @SafeCallback void doCallback(@NonNull String message) { FinishDialog.newInstance().show(getSupportFragmentManager(), "TAG"); } } !4BGF$BMMCBDL ͔ΘΓʹͪ͜ΒΛݺͼग़͢
  28. 7VMUVSF @Override protected void onResume() { super.onResume(); SafeMainActivity.register(this); } @Override

    protected void onPause() { SafeMainActivity.unregister(); super.onPause(); }
  29. 7VMUVSF @Override protected void onResume() { super.onResume(); SafeMainActivity.register(this); } @Override

    protected void onPause() { SafeMainActivity.unregister(); super.onPause(); } ҕৡ