Skip to content

Commit

Permalink
Copy explicit serialVersionUID from @AutoOneOf classes to their g…
Browse files Browse the repository at this point in the history
…enerated subclasses.

Previously the subclasses did not have an explicit `serialVersionUID`, so their implicit ones were likely to change if any details of the code-generation changed.

This change BREAKS SERIAL COMPATIBILITY for `@AutoOneOf` classes that had an explicit `serialVersionUID`.

Also, don't bother generating the shared `Parent_` class in the degenerate case of an `@AutoOneOf` class with no alternatives.

These changes reduce the number of warnings from `CompileWithEclipseTest` from 11 to 3.

RELNOTES=If an `@AutoOneOf` class has a `serialVersionUID` this is now copied to its generated subclasses. THIS BREAKS SERIAL COMPATIBILITY for `@AutoOneOf` classes with explicit `serialVersionUID` declarations, though those were already liable to be broken by arbitrary changes to the generated AutoOneOf code.
PiperOrigin-RevId: 364387942
  • Loading branch information
eamonnmcmanus authored and Google Java Core Libraries committed Mar 22, 2021
1 parent f14d633 commit 71d8121
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,7 @@ final void defineSharedVarsForType(
vars.equals = methodsToGenerate.containsKey(ObjectMethod.EQUALS);
vars.hashCode = methodsToGenerate.containsKey(ObjectMethod.HASH_CODE);
vars.equalsParameterType = equalsParameterType(methodsToGenerate);
vars.serialVersionUID = getSerialVersionUID(type);
}

/** Returns the spelling to be used in the generated code for the given list of annotations. */
Expand Down Expand Up @@ -833,8 +834,9 @@ public Boolean visitArray(List<? extends AnnotationValue> list, Void p) {
}

/**
* Returns a string like {@code "1234L"} if {@code type instanceof Serializable} and defines
* {@code serialVersionUID = 1234L}; otherwise {@code ""}.
* Returns a string like {@code "private static final long serialVersionUID = 1234L"} if {@code
* type instanceof Serializable} and defines {@code serialVersionUID = 1234L}; otherwise {@code
* ""}.
*/
final String getSerialVersionUID(TypeElement type) {
TypeMirror serializable = elementUtils().getTypeElement(Serializable.class.getName()).asType();
Expand All @@ -846,7 +848,7 @@ final String getSerialVersionUID(TypeElement type) {
if (field.getModifiers().containsAll(Arrays.asList(Modifier.STATIC, Modifier.FINAL))
&& field.asType().getKind() == TypeKind.LONG
&& value != null) {
return value + "L";
return "private static final long serialVersionUID = " + value + "L;";
} else {
errorReporter.reportError(
field, "serialVersionUID must be a static final long compile-time constant");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,11 @@ abstract class AutoValueOrOneOfTemplateVars extends TemplateVars {
* wildcard, for example {@code <?, ?>}.
*/
String wildcardTypes;

/**
* The text of the complete serialVersionUID declaration, or empty if there is none. When
* non-empty, it will be something like {@code private static final long serialVersionUID =
* 123L;}.
*/
String serialVersionUID;
}
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,6 @@ private void defineVarsForType(
propertyMethodAnnotationMap(type, propertyMethods);
vars.props =
propertySet(propertyMethodsAndTypes, annotatedPropertyFields, annotatedPropertyMethods);
vars.serialVersionUID = getSerialVersionUID(type);
// Check for @AutoValue.Builder and add appropriate variables if it is present.
maybeBuilder.ifPresent(
builder -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,6 @@ class AutoValueTemplateVars extends AutoValueOrOneOfTemplateVars {
*/
String gwtCompatibleAnnotation;

/** The text of the serialVersionUID constant, or empty if there is none. */
String serialVersionUID;

/** The simple name of the generated subclass. */
String subclass;
/**
Expand Down
10 changes: 8 additions & 2 deletions value/src/main/java/com/google/auto/value/processor/autooneof.vm
Original file line number Diff line number Diff line change
Expand Up @@ -94,19 +94,23 @@ final class $generatedClass {

#end

#if (!$props.empty)
// Parent class that each implementation will inherit from.
private abstract static class Parent_$formalTypes extends $origClass$actualTypes {

#foreach ($p in $props)
$serialVersionUID

#foreach ($p in $props)

@`java.lang.Override`
$p.access $p.type ${p.getter}() {
throw new UnsupportedOperationException(${kindGetter}().toString());
}

#end
#end

}
#end

#foreach ($p in $props)

Expand All @@ -120,6 +124,8 @@ final class $generatedClass {
// Implementation when the contained property is "${p}".
private static final class Impl_$p$formalTypes extends Parent_$actualTypes {

$serialVersionUID

#if ($p.type == "void")

// There is only one instance of this class.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,7 @@ ${modifiers}class $subclass$formalTypes extends $origClass$actualTypes {
}
#end

#if (!$serialVersionUID.empty)
private static final long serialVersionUID = $serialVersionUID;
#end
$serialVersionUID

#if ($builderTypeName != "")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ public void success() {
"import java.io.Serializable;",
"",
"@AutoOneOf(TaskResult.Kind.class)",
"public abstract class TaskResult<V, T extends Throwable> {",
"public abstract class TaskResult<V, T extends Throwable> implements Serializable {",
" private static final long serialVersionUID = 1234L;",
"",
" public enum Kind {VALUE, EXCEPTION, EMPTY}",
" public abstract Kind getKind();",
"",
Expand Down Expand Up @@ -92,6 +94,8 @@ public void success() {
" // Parent class that each implementation will inherit from.",
" private abstract static class Parent_<V, T extends Throwable> "
+ "extends TaskResult<V, T> {",
" private static final long serialVersionUID = 1234L;",
"",
" @Override",
" public V value() {",
" throw new UnsupportedOperationException(getKind().toString());",
Expand All @@ -111,6 +115,8 @@ public void success() {
" // Implementation when the contained property is \"value\".",
" private static final class Impl_value<V, T extends Throwable> "
+ "extends Parent_<V, T> {",
" private static final long serialVersionUID = 1234L;",
"",
" private final V value;",
"",
" Impl_value(V value) {",
Expand Down Expand Up @@ -152,6 +158,8 @@ public void success() {
" // Implementation when the contained property is \"exception\".",
" private static final class Impl_exception<V, T extends Throwable> "
+ "extends Parent_<V, T> {",
" private static final long serialVersionUID = 1234L;",
"",
" private final Throwable exception;",
"",
" Impl_exception(Throwable exception) {",
Expand Down Expand Up @@ -193,13 +201,19 @@ public void success() {
" // Implementation when the contained property is \"empty\".",
" private static final class Impl_empty<V, T extends Throwable> "
+ "extends Parent_<V, T> {",
" private static final long serialVersionUID = 1234L;",
"",
" static final Impl_empty<?, ?> INSTANCE = new Impl_empty<>();",
"",
" private Impl_empty() {}",
"",
" @Override",
" public void empty() {}",
"",
" private Object readResolve() {",
" return INSTANCE;",
" }",
"",
" @Override",
" public String toString() {",
" return \"TaskResult{empty}\";",
Expand Down

0 comments on commit 71d8121

Please sign in to comment.