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

AutoValue Extensions

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