diff --git a/value/src/main/java/com/google/auto/value/processor/AutoValueProcessor.java b/value/src/main/java/com/google/auto/value/processor/AutoValueProcessor.java index 7d717698f9..b527b739e9 100644 --- a/value/src/main/java/com/google/auto/value/processor/AutoValueProcessor.java +++ b/value/src/main/java/com/google/auto/value/processor/AutoValueProcessor.java @@ -357,7 +357,7 @@ private void processType(TypeElement type) { errorReporter.abortWithError("@AutoValue may not be used to implement an annotation" + " interface; try using @AutoAnnotation instead", type); } - checkTopLevelOrStatic(type); + checkModifiersIfNested(type); ImmutableSet methods = getLocalAndInheritedMethods(type, processingEnv.getElementUtils()); @@ -565,11 +565,15 @@ private String nameWithoutPrefix(String name) { return Introspector.decapitalize(name); } - private void checkTopLevelOrStatic(TypeElement type) { + private void checkModifiersIfNested(TypeElement type) { ElementKind enclosingKind = type.getEnclosingElement().getKind(); - if ((enclosingKind.isClass() || enclosingKind.isInterface()) - && !type.getModifiers().contains(Modifier.STATIC)) { - errorReporter.abortWithError("Nested @AutoValue class must be static", type); + if (enclosingKind.isClass() || enclosingKind.isInterface()) { + if (type.getModifiers().contains(Modifier.PRIVATE)) { + errorReporter.abortWithError("@AutoValue class must not be private", type); + } + if (!type.getModifiers().contains(Modifier.STATIC)) { + errorReporter.abortWithError("Nested @AutoValue class must be static", type); + } } // In principle type.getEnclosingElement() could be an ExecutableElement (for a class // declared inside a method), but since RoundEnvironment.getElementsAnnotatedWith doesn't diff --git a/value/src/test/java/com/google/auto/value/processor/CompilationTest.java b/value/src/test/java/com/google/auto/value/processor/CompilationTest.java index c5a33be75c..ea9f37c94f 100644 --- a/value/src/test/java/com/google/auto/value/processor/CompilationTest.java +++ b/value/src/test/java/com/google/auto/value/processor/CompilationTest.java @@ -242,6 +242,31 @@ public void autoValueMustBeStatic() { .in(javaFileObject).onLine(7); } + @Test + public void autoValueMustBeNotBePrivate() { + JavaFileObject javaFileObject = JavaFileObjects.forSourceLines( + "foo.bar.Baz", + "package foo.bar;", + "", + "import com.google.auto.value.AutoValue;", + "", + "public class Baz {", + " @AutoValue", + " private abstract static class Private {", + " public abstract String buh();", + " public Private create(String buh) {", + " return new AutoValue_Baz_Private(buh);", + " }", + " }", + "}"); + assertAbout(javaSource()) + .that(javaFileObject) + .processedWith(new AutoValueProcessor()) + .failsToCompile() + .withErrorContaining("@AutoValue class must not be private") + .in(javaFileObject).onLine(7); + } + @Test public void noMultidimensionalPrimitiveArrays() throws Exception { JavaFileObject javaFileObject = JavaFileObjects.forSourceLines(