From 07f37b2be9e060f57eed3e3f5cdccab6a53f0927 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89amonn=20McManus?= Date: Mon, 13 Dec 2021 07:55:03 -0800 Subject: Disallow `@AutoValue final class`. We will otherwise try to generate a subclass for it which obviously won't compile. This is pretty unlikely anyway since a non-trivial `@AutoValue` class has to be abstract and a class can't be both final and abstract. Fixes https://github.com/google/auto/issues/1215. RELNOTES=n/a PiperOrigin-RevId: 416042702 --- .../value/processor/AutoValueishProcessor.java | 9 +++++++- .../value/processor/AutoValueCompilationTest.java | 25 +++++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) (limited to 'value/src') diff --git a/value/src/main/java/com/google/auto/value/processor/AutoValueishProcessor.java b/value/src/main/java/com/google/auto/value/processor/AutoValueishProcessor.java index 56e8a98a..31f1ec1c 100644 --- a/value/src/main/java/com/google/auto/value/processor/AutoValueishProcessor.java +++ b/value/src/main/java/com/google/auto/value/processor/AutoValueishProcessor.java @@ -417,7 +417,7 @@ abstract class AutoValueishProcessor extends AbstractProcessor { /** * Validations common to all the subclasses. An {@code @AutoFoo} type must be a class, or possibly * an interface for {@code @AutoBuilder}. If it is a class then it must have a non-private no-arg - * constructor. + * constructor. And, since we'll be generating a subclass, it can't be final. */ private void validateType(TypeElement type) { ElementKind kind = type.getKind(); @@ -441,6 +441,13 @@ abstract class AutoValueishProcessor extends AbstractProcessor { simpleAnnotationName, simpleAnnotationName); } + if (type.getModifiers().contains(Modifier.FINAL)) { + errorReporter.abortWithError( + type, + "[%sFinal] @%s class must not be final", + simpleAnnotationName, + simpleAnnotationName); + } } /** diff --git a/value/src/test/java/com/google/auto/value/processor/AutoValueCompilationTest.java b/value/src/test/java/com/google/auto/value/processor/AutoValueCompilationTest.java index cd21ef37..09d4faf9 100644 --- a/value/src/test/java/com/google/auto/value/processor/AutoValueCompilationTest.java +++ b/value/src/test/java/com/google/auto/value/processor/AutoValueCompilationTest.java @@ -576,6 +576,29 @@ public class AutoValueCompilationTest { .onLineContaining("interface Baz"); } + @Test + public void autoValueMustNotBeFinal() { + JavaFileObject javaFileObject = + JavaFileObjects.forSourceLines( + "foo.bar.Baz", + "package foo.bar;", + "", + "import com.google.auto.value.AutoValue;", + "", + "@AutoValue", + "public final class Baz {", + " public Baz create() {", + " return new AutoValue_Baz();", + " }", + "}"); + Compilation compilation = + javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject); + assertThat(compilation) + .hadErrorContaining("@AutoValue class must not be final") + .inFile(javaFileObject) + .onLineContaining("class Baz"); + } + @Test public void autoValueMustBeStatic() { JavaFileObject javaFileObject = @@ -603,7 +626,7 @@ public class AutoValueCompilationTest { } @Test - public void autoValueMustBeNotBePrivate() { + public void autoValueMustNotBePrivate() { JavaFileObject javaFileObject = JavaFileObjects.forSourceLines( "foo.bar.Baz", -- cgit v1.2.3