Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recognize AutoValue extension generated code in ClassInitializationDeadlock and AutoValueSubclassLeaked #4508

Merged
merged 1 commit into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Type;
import java.util.regex.Pattern;

/** Matches {@code AutoValue_} uses outside the containing file. */
@BugPattern(
Expand All @@ -55,6 +56,8 @@
public final class AutoValueSubclassLeaked extends BugChecker
implements CompilationUnitTreeMatcher {

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

@Override
public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState state) {
ImmutableSet<Type> autoValueClassesFromThisFile = findAutoValueClasses(tree, state);
Expand Down Expand Up @@ -91,7 +94,7 @@ public Void visitIdentifier(IdentifierTree identifierTree, Void unused) {
private void handle(Tree tree) {
Symbol symbol = getSymbol(tree);
if (symbol instanceof ClassSymbol
&& symbol.getSimpleName().toString().startsWith("AutoValue_")
&& AUTO_VALUE_PREFIX.matcher(symbol.getSimpleName().toString()).matches()
&& autoValueClassesFromThisFile.stream()
.noneMatch(av -> isSubtype(symbol.type, av, state))) {
state.reportMatch(describeMatch(tree));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,15 @@
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.Types;
import java.util.regex.Pattern;
import javax.lang.model.element.ElementKind;

/** See the summary. */
@BugPattern(summary = "Possible class initialization deadlock", severity = WARNING)
public class ClassInitializationDeadlock extends BugChecker implements BugChecker.ClassTreeMatcher {

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

@Override
public Description matchClass(ClassTree tree, VisitorState state) {
ClassSymbol classSymbol = getSymbol(tree);
Expand Down Expand Up @@ -211,7 +215,7 @@ boolean nonPrivateInstantiator(ClassSymbol use) {
// methods), it can't be directly instantiated outside the current file.
return false;
}
if (use.getSimpleName().toString().startsWith("AutoValue_")) {
if (AUTO_VALUE_PREFIX.matcher(use.getSimpleName().toString()).matches()) {
// AutoValue generated code is necessarily package-private, but should only be accessed
// within the declaration of the corresponding base class. See also the discussion of
// AutoValue in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,4 +124,33 @@ public void generatedCode() {
"}")
.doTest();
}

@Test
public void positiveAutoValueExtension() {
helper
.addSourceLines(
"$$AutoValue_Foo.java", //
"package test;",
"class $$AutoValue_Foo extends Test.Foo {",
"}")
.addSourceLines(
"Test.java",
"package test;",
"import com.google.auto.value.AutoValue;",
"class Test {",
" @AutoValue",
" abstract static class Foo {",
" }",
"}")
.addSourceLines(
"Bar.java",
"package test;",
"class Bar {",
" public static Test.Foo create() {",
" // BUG: Diagnostic contains:",
" return new $$AutoValue_Foo();",
" }",
"}")
.doTest();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -309,4 +309,21 @@ public void nonNestedSubclass() {
"class B extends A {}")
.doTest();
}

@Test
public void negativeAutoValueExtension() {
testHelper
.addSourceLines(
"$$AutoValue_Foo.java", //
"class $$AutoValue_Foo extends Foo {",
"}")
.addSourceLines(
"A.java",
"import com.google.auto.value.AutoValue;",
"@AutoValue",
"abstract class Foo {",
" private static final Foo FOO = new $$AutoValue_Foo();",
"}")
.doTest();
}
}
Loading