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

AutoValue Extensions

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.

AutoValue Extensions

Avatar for Gabriel Ittner

Gabriel Ittner

September 28, 2016
Tweet

More Decks by Gabriel Ittner

Other Decks in Programming

Transcript

  1. How do we make a value type out of this?

    public class User { public String id; public String name; public String email; }
  2. How do we make a value type out of this?

    • immutable public class User { public String id; public String name; public String email; }
  3. How do we make a value type out of this?

    • immutable • identityless public class User { public String id; public String name; public String email; }
  4. Value type public class User { public final String id;

    public final String name; public final String email; public User(String id, String name, String email) { this.id = id; this.name = name; this.email = email; } }
  5. Value type public class User { private final String id;

    private final String name; private final String email; public User(String id, String name, String email) { this.id = id; this.name = name; this.email = email; } public String id() { return id; } public String name() { return name; } public String email() { return email; } }
  6. Value type public final class User { private final String

    id; private final String name; private final String email; public User(String id, String name, String email) { this.id = id; this.name = name; this.email = email; } public String id() { return id; } public String name() { return name; } public String email() { return email; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User user = (User) o; if (!id.equals(user.id)) return false; if (!name.equals(user.name)) return false; return email.equals(user.email); } @Override public int hashCode() { int result = id.hashCode(); result = 31 * result + name.hashCode(); result = 31 * result + email.hashCode(); return result; } }
  7. Value type public final class User { private final String

    id; private final String name; private final String email; public User(String id, String name, String email) { this.id = id; this.name = name; this.email = email; } public String id() { return id; } public String name() { return name; } public String email() { return email; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User user = (User) o; if (!id.equals(user.id)) return false; if (!name.equals(user.name)) return false; return email.equals(user.email); } @Override public int hashCode() { int result = id.hashCode(); result = 31 * result + name.hashCode(); result = 31 * result + email.hashCode(); return result; } @Override public String toString() { return "User{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", email='" + email + '\'' + '}'; } }
  8. Value type public final class User { private final String

    id; private final String name; private final String email; public User(String id, String name, String email) { this.id = id; this.name = name; this.email = email; } public String id() { return id; } public String name() { return name; } public String email() { return email; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User user = (User) o; if (!id.equals(user.id)) return false; if (!name.equals(user.name)) return false; return email.equals(user.email); } @Override public int hashCode() { int result = id.hashCode(); result = 31 * result + name.hashCode(); result = 31 * result + email.hashCode(); return result; } @Override public String toString() { return "User{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", email='" + email + '\'' + '}'; } }
  9. Value type public final class User { private final String

    id; private final String name; private final String email; private final String profilePicture; public User(String id, String name, String email, String profilePicture) { this.id = id; this.name = name; this.email = email; this.profilePicture = profilePicture; } public String id() { return id; } public String name() { return name; } public String email() { return email; } public String profilePicture() { return profilePicture; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User user = (User) o; if (!id.equals(user.id)) return false; if (!name.equals(user.name)) return false; if (!email.equals(user.email)) return false; return profilePicture.equals(user.profilePicture); } @Override public int hashCode() { int result = id.hashCode(); result = 31 * result + name.hashCode(); result = 31 * result + email.hashCode(); result = 31 * result + profilePicture.hashCode(); return result; } @Override public String toString() { return "User{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", email='" + email + '\'' + ", profilePicture='" + profilePicture + '\'' + '}'; }
  10. AutoValue public abstract class User { public abstract String id();

    public abstract String name(); public abstract String email(); }
  11. AutoValue @AutoValue public abstract class User { public abstract String

    id(); public abstract String name(); public abstract String email(); }
  12. AutoValue @AutoValue public abstract class User { public abstract String

    id(); public abstract String name(); public abstract String email(); } @Generated("com.google.auto.value.processor.AutoValueProcessor") final class AutoValue_User extends User { // value type implementation }
  13. AutoValue Extensions • AutoParcel - fork to support Parcelable •

    Ryan Harter contributes extension support • Version 1.2 - provisional support
  14. AutoValue Extensions • AutoParcel - fork to support Parcelable •

    Ryan Harter contributes extension support • Version 1.2 - provisional support • Version 1.3 - stable API
  15. auto-value-parcel @AutoValue public abstract class User { public abstract String

    id(); public abstract String name(); public abstract String email(); }
  16. auto-value-parcel @AutoValue public abstract class User implements Parcelable { public

    abstract String id(); public abstract String name(); public abstract String email(); }
  17. auto-value-parcel @AutoValue public abstract class User implements Parcelable { public

    abstract String id(); public abstract String name(); public abstract String email(); } abstract class $AutoValue_User extends User { // value type implementation }
  18. auto-value-parcel @AutoValue public abstract class User implements Parcelable { public

    abstract String id(); public abstract String name(); public abstract String email(); } abstract class $AutoValue_User extends User { // value type implementation } final class AutoValue_User extends $AutoValue_User { // parcelable implementation }
  19. auto-value-with @AutoValue public abstract class User { public abstract String

    id(); public abstract String name(); public abstract String email(); }
  20. auto-value-with @AutoValue public abstract class User { public abstract String

    id(); public abstract String name(); public abstract String email(); public abstract User withEmail(String email); }
  21. auto-value-with @AutoValue public abstract class User { public abstract String

    id(); public abstract String name(); public abstract String email(); public abstract User withEmail(String email); } abstract class $AutoValue_User extends User { ... }
  22. auto-value-with @AutoValue public abstract class User { public abstract String

    id(); public abstract String name(); public abstract String email(); public abstract User withEmail(String email); } abstract class $AutoValue_User extends User { ... } final class AutoValue_User extends $AutoValue_User { public User withEmail(String email) { return new AutoValue_User(id(), name(), email); } }
  23. Multiple extensions abstract class $$AutoValue_User extends User { // value

    type implementation } abstract class $AutoValue_User extends $$AutoValue_User { // with implementation } final class AutoValue_User extends $AutoValue_User { // parcelable implementation }
  24. Other extensions • github.com/rharter/ auto-value-parcel • github.com/gabrielittner/ auto-value-with • github.com/gabrielittner/

    auto-value-cursor • github.com/rharter/ auto-value-gson • github.com/rharter/ auto-value-moshi
  25. Other extensions • github.com/rharter/ auto-value-parcel • github.com/gabrielittner/ auto-value-with • github.com/gabrielittner/

    auto-value-cursor • github.com/rharter/ auto-value-gson • github.com/rharter/ auto-value-moshi • github.com/square/ auto-value-redacted
  26. Other extensions • github.com/rharter/ auto-value-parcel • github.com/gabrielittner/ auto-value-with • github.com/gabrielittner/

    auto-value-cursor • github.com/rharter/ auto-value-gson • github.com/rharter/ auto-value-moshi • github.com/square/ auto-value-redacted • github.com/mattlogan/ auto-value-firebase
  27. Extension API public abstract class AutoValueExtension { public boolean applicable(Context

    context) { } public boolean mustBeFinal(Context context) { } public Set<String> consumeProperties(Context context) { } public Set<ExecutableElement> consumeMethods(Context context) { } public abstract String generateClass(Context context, String className, String classToExtend, boolean isFinal); }
  28. Extension API public abstract class AutoValueExtension { public boolean applicable(Context

    context) { } public boolean mustBeFinal(Context context) { } public Set<String> consumeProperties(Context context) { } public Set<ExecutableElement> consumeMethods(Context context) { } public abstract String generateClass(Context context, String className, String classToExtend, boolean isFinal); }
  29. Extension API public interface Context { /* ... */ TypeElement

    autoValueClass(); Map<String, ExecutableElement> properties(); Set<ExecutableElement> abstractMethods(); }
  30. Extension API public interface Context { /* ... */ TypeElement

    autoValueClass(); Map<String, ExecutableElement> properties(); Set<ExecutableElement> abstractMethods(); }
  31. Extension API public interface Context { /* ... */ TypeElement

    autoValueClass(); Map<String, ExecutableElement> properties(); Set<ExecutableElement> abstractMethods(); }
  32. Extension API public interface Context { /* ... */ TypeElement

    autoValueClass(); Map<String, ExecutableElement> properties(); Set<ExecutableElement> abstractMethods(); }
  33. Extension API public abstract class AutoValueExtension { public boolean applicable(Context

    context) { } public boolean mustBeFinal(Context context) { } public Set<String> consumeProperties(Context context) { } public Set<ExecutableElement> consumeMethods(Context context) { } public abstract String generateClass(Context context, String className, String classToExtend, boolean isFinal); }
  34. Extension API public abstract class AutoValueExtension { public boolean applicable(Context

    context) { } public boolean mustBeFinal(Context context) { } public Set<String> consumeProperties(Context context) { } public Set<ExecutableElement> consumeMethods(Context context) { } public abstract String generateClass(Context context, String className, String classToExtend, boolean isFinal); }
  35. Extension API public abstract class AutoValueExtension { public boolean applicable(Context

    context) { } public boolean mustBeFinal(Context context) { } public Set<String> consumeProperties(Context context) { } public Set<ExecutableElement> consumeMethods(Context context) { } public abstract String generateClass(Context context, String className, String classToExtend, boolean isFinal); }
  36. Extension API public abstract class AutoValueExtension { public boolean applicable(Context

    context) { } public boolean mustBeFinal(Context context) { } public Set<String> consumeProperties(Context context) { } public Set<ExecutableElement> consumeMethods(Context context) { } public abstract String generateClass(Context context, String className, String classToExtend, boolean isFinal); }
  37. Extension API public abstract class AutoValueExtension { public boolean applicable(Context

    context) { } public boolean mustBeFinal(Context context) { } public Set<String> consumeProperties(Context context) { } public Set<ExecutableElement> consumeMethods(Context context) { } public abstract String generateClass(Context context, String className, String classToExtend, boolean isFinal); }
  38. Extension API public abstract class AutoValueExtension { public boolean applicable(Context

    context) { } public boolean mustBeFinal(Context context) { } public Set<String> consumeProperties(Context context) { } public Set<ExecutableElement> consumeMethods(Context context) { } public abstract String generateClass(Context context, String className, String classToExtend, boolean isFinal); }
  39. Extension API public Set<String> consumeProperties(Context context) { return Collections.singletonSet("describeContents"); }

    public Set<ExecutableElement> consumeMethods(Context context) { return getWriteToParcelMethod(context.abstractMethods()); }
  40. Extension API public Set<String> consumeProperties(Context context) { return Collections.emptySet(); }

    public Set<ExecutableElement> consumeMethods(Context context) { return getWitherMethods(context.abstractMethods()); }
  41. Extension API public abstract class AutoValueExtension { public boolean applicable(Context

    context) { } public boolean mustBeFinal(Context context) { } public Set<String> consumeProperties(Context context) { } public Set<ExecutableElement> consumeMethods(Context context) { } public abstract String generateClass(Context context, String className, String classToExtend, boolean isFinal); }
  42. Extension API public abstract class AutoValueExtension { public boolean applicable(Context

    context) { } public boolean mustBeFinal(Context context) { } public Set<String> consumeProperties(Context context) { } public Set<ExecutableElement> consumeMethods(Context context) { } public abstract String generateClass(Context context, String className, String classToExtend, boolean isFinal); }
  43. Extension API public abstract class AutoValueExtension { public boolean applicable(Context

    context) { } public boolean mustBeFinal(Context context) { } public Set<String> consumeProperties(Context context) { } public Set<ExecutableElement> consumeMethods(Context context) { } public abstract String generateClass(Context context, String className, String classToExtend, boolean isFinal); }