Skip to content

Commit

Permalink
Improve handling of AutoValue extensions in AutoValueSubclassLeaked
Browse files Browse the repository at this point in the history
Follow-up to 5413aa5

Don't rely on the extension generated code having `@Generated` annotations. A number of extensions omit the annotation, and AutoValueSubclassLeaked relies on the generated annotation to recognize generated code, so after 5413aa5 it was reporting errors for references from extensions.

PiperOrigin-RevId: 657715233
  • Loading branch information
cushon authored and Error Prone Team committed Jul 30, 2024
1 parent 5413aa5 commit ca7b569
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import static com.google.errorprone.util.ASTHelpers.hasAnnotation;
import static com.google.errorprone.util.ASTHelpers.isSubtype;

import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableSet;
import com.google.errorprone.BugPattern;
import com.google.errorprone.VisitorState;
Expand All @@ -39,6 +38,7 @@
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.TypeTag;
import java.util.regex.Pattern;

/** Matches {@code AutoValue_} uses outside the containing file. */
Expand All @@ -58,6 +58,8 @@ public final class AutoValueSubclassLeaked extends BugChecker

private static final Pattern AUTO_VALUE_PREFIX = Pattern.compile("\\$*AutoValue_.*");

private static final String AUTO_VALUE_ANNOTATION = "com.google.auto.value.AutoValue";

@Override
public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState state) {
ImmutableSet<Type> autoValueClassesFromThisFile = findAutoValueClasses(tree, state);
Expand Down Expand Up @@ -110,9 +112,20 @@ private static ImmutableSet<Type> findAutoValueClasses(
new TreeScanner<Void, Void>() {
@Override
public Void visitClass(ClassTree classTree, Void unused) {
if (hasAnnotation(classTree, AutoValue.class, state)) {
if (hasAnnotation(classTree, AUTO_VALUE_ANNOTATION, state)) {
types.add(getType(classTree));
}
ClassSymbol classSymbol = getSymbol(classTree);
if (AUTO_VALUE_PREFIX.matcher(classSymbol.getSimpleName().toString()).matches()) {
for (Type type = classSymbol.asType();
!type.hasTag(TypeTag.NONE);
type = state.getTypes().supertype(type)) {
if (hasAnnotation(type.asElement(), AUTO_VALUE_ANNOTATION, state)) {
types.add(type);
break;
}
}
}
return super.visitClass(classTree, null);
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,4 +153,43 @@ public void positiveAutoValueExtension() {
"}")
.doTest();
}

@Test
public void positiveAutoValueExtension_noGeneratedAnnotation() {
CompilationTestHelper.newInstance(AutoValueSubclassLeaked.class, getClass())
.addSourceLines(
"$AutoValue_Test_Foo.java", //
"package test;",
"final class AutoValue_Test_Foo extends $AutoValue_Test_Foo {",
" static final Test.Foo AUTO_VALUE = new AutoValue_Test_Foo();",
"}")
.addSourceLines(
"$AutoValue_Test_Foo.java", //
"package test;",
"import javax.annotation.processing.Generated;",
"@Generated(\"com.google.auto.value.processor.AutoValueProcessor\")",
"class $AutoValue_Test_Foo extends Test.Foo {",
"}")
.addSourceLines(
"Test.java",
"package test;",
"import com.google.auto.value.AutoValue;",
"class Test {",
" static final Test.Foo EXTENSION = new $AutoValue_Test_Foo();",
" static final Test.Foo AUTO_VALUE = new AutoValue_Test_Foo();",
" @AutoValue",
" abstract static class Foo {",
" }",
"}")
.addSourceLines(
"Bar.java",
"package test;",
"class Bar {",
" // BUG: Diagnostic contains:",
" static final Test.Foo EXTENSION = new $AutoValue_Test_Foo();",
" // BUG: Diagnostic contains:",
" static final Test.Foo AUTO_VALUE = new AutoValue_Test_Foo();",
"}")
.doTest();
}
}

0 comments on commit ca7b569

Please sign in to comment.