Skip to content

Commit

Permalink
ExtendsAutoValue: walk up the tree to see if an enclosing class is @g…
Browse files Browse the repository at this point in the history
…enerated

***

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=285998243
  • Loading branch information
awturner authored and kluever committed Dec 18, 2019
1 parent 9574b12 commit e05fa7a
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1274,11 +1274,12 @@ public static ImmutableSet<String> getGeneratedBy(VisitorState state) {
return getGeneratedBy(getSymbol(outerClass), state);
}


/**
* Returns the values of the given symbol's {@code javax.annotation.Generated} or {@code
* javax.annotation.processing.Generated} annotation, if present.
*/
public static ImmutableSet<String> getGeneratedBy(ClassSymbol symbol, VisitorState state) {
public static ImmutableSet<String> getGeneratedBy(Symbol symbol, VisitorState state) {
checkNotNull(symbol);
Optional<Compound> c =
Stream.of("javax.annotation.Generated", "javax.annotation.processing.Generated")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package com.google.errorprone.bugpatterns;

import static com.google.common.collect.Streams.stream;

import com.google.common.collect.ImmutableSet;
import com.google.errorprone.BugPattern;
import com.google.errorprone.BugPattern.SeverityLevel;
Expand All @@ -26,6 +28,7 @@
import com.google.errorprone.util.ASTHelpers;
import com.sun.source.tree.ClassTree;
import com.sun.tools.javac.util.Name;
import java.util.Objects;

/** Makes sure that you are not extending a class that has @AutoValue as an annotation. */
@BugPattern(
Expand All @@ -43,24 +46,29 @@ public final class ExtendsAutoValue extends BugChecker implements ClassTreeMatch

@Override
public Description matchClass(ClassTree tree, VisitorState state) {

if (!ASTHelpers.getGeneratedBy(ASTHelpers.getSymbol(tree), state).isEmpty()) {
// Skip generated code. Yes, I know we can do this via a flag but we should always ignore
// generated code, so to be sure, manually check it.
return Description.NO_MATCH;
}

if (tree.getExtendsClause() == null) {
// Doesn't extend anything, can't possibly be a violation.
return Description.NO_MATCH;
}

if (!ASTHelpers.annotationsAmong(
ASTHelpers.getSymbol(tree.getExtendsClause()), AUTOS.get(state), state)
.isEmpty()) {
// Violation: one of its superclasses extends AutoValue.
return buildDescription(tree).build();
if (!isInGeneratedCode(state)) {
return buildDescription(tree).build();
}
}

return Description.NO_MATCH;
}

private static boolean isInGeneratedCode(VisitorState state) {
// Skip generated code. Yes, I know we can do this via a flag but we should always ignore
// generated code, so to be sure, manually check it.
return stream(state.getPath())
.map(ASTHelpers::getSymbol)
.filter(Objects::nonNull)
.anyMatch(sym -> !ASTHelpers.getGeneratedBy(sym, state).isEmpty());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -150,4 +150,37 @@ public void extendsAutoValue_badButSuppressed() {
"public class TestClass extends AutoClass {}")
.doTest();
}

@Test
public void extendsAutoValue_innerClassExtends() {
helper
.addSourceLines(
"TestClass.java",
"import com.google.auto.value.AutoValue;",
"@AutoValue class AutoClass {}",
"",
"public class TestClass {",
" // BUG: Diagnostic contains: ExtendsAutoValue",
" public class Extends extends AutoClass {}",
"}")
.doTest();
}

@Test
public void extendsAutoValue_innerClassExtends_generated() {
helper
.addSourceLines(
"TestClass.java",
"import com.google.auto.value.AutoValue;",
(RuntimeVersion.isAtLeast9()
? "import javax.annotation.processing.Generated;"
: "import javax.annotation.Generated;"),
"@AutoValue class AutoClass {}",
"",
"@Generated(\"generator\")",
"public class TestClass {",
" public class Extends extends AutoClass {}",
"}")
.doTest();
}
}

0 comments on commit e05fa7a

Please sign in to comment.