paperparcel icon indicating copy to clipboard operation
paperparcel copied to clipboard

Fields generated by `@Memoized` should be excluded automatically

Open ansman opened this issue 8 years ago • 4 comments

This class:

public abstract class Foo {
    @Memoized
    public String someMethod() {
        return "foo";
    }
}

Will generate a field called someMethod that unfortunately isn't transient so PaperParcel complains. Ideally they should be excluded automatically.

ansman avatar Jun 08 '17 18:06 ansman

Are you able to decompile the bytecode into Java and post it here? (I don't have any means of doing this myself because I'm currently in the process of moving overseas)

grandstaish avatar Jun 08 '17 22:06 grandstaish

This class:

@AutoValue
public abstract class Foo {
    @Memoized
    public String foo() {
        return "foo";
    }
}

generates

@Generated("com.google.auto.value.processor.AutoValueProcessor")
 abstract class $AutoValue_Foo extends Foo {

  $AutoValue_Foo(
 ) {
  }

  @Override
  public String toString() {
    return "Foo{"
        + "}";
  }

  @Override
  public boolean equals(Object o) {
    if (o == this) {
      return true;
    }
    if (o instanceof Foo) {
      return true;
    }
    return false;
  }

  @Override
  public int hashCode() {
    int h = 1;
    return h;
  }

}

and

@Generated("com.google.auto.value.extension.memoized.MemoizeExtension")
final class AutoValue_Foo extends $AutoValue_Foo {
  private volatile String foo;

  AutoValue_Foo() {
    super();
  }

  @Override
  public String foo() {
    if (foo == null) {
      synchronized (this) {
        if (foo == null) {
          foo = super.foo();
          if (foo == null) {
            throw new NullPointerException("foo() cannot return null");
          }
        }
      }
    }
    return foo;
  }
}

The field always has the same name as the method.

If the field is nullable or primitive this is generated:

@Generated("com.google.auto.value.extension.memoized.MemoizeExtension")
final class AutoValue_Foo extends $AutoValue_Foo {
  private volatile String foo;

  private volatile boolean foo$Memoized;

  AutoValue_Foo() {
    super();
  }

  @Override
  @Nullable
  public String foo() {
    if (!foo$Memoized) {
      synchronized (this) {
        if (!foo$Memoized) {
          foo = super.foo();
          foo$Memoized = true;
        }
      }
    }
    return foo;
  }
}

ansman avatar Jun 09 '17 07:06 ansman

It's a workaround, but for now you could exclude all volatile fields from being parcelled. You can do it globally via the ProcessorConfig:

@ProcessorConfig(
  options = @PaperParcel.Options(
    excludeModifiers = { Modifier.TRANSIENT, Modifier.STATIC, Modifier.VOLATILE }
  )
)

grandstaish avatar Jun 11 '17 11:06 grandstaish

Yeah, that's what I did now. Ideally this issue should be fixed: https://github.com/google/auto/issues/406

ansman avatar Jun 11 '17 12:06 ansman