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

CanIgnoreReturnValueSuggester: Support additional exempting method annotations #4009

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@
import static com.google.errorprone.util.ASTHelpers.stripParentheses;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.errorprone.BugPattern;
import com.google.errorprone.ErrorProneFlags;
import com.google.errorprone.VisitorState;
import com.google.errorprone.bugpatterns.BugChecker;
import com.google.errorprone.bugpatterns.BugChecker.MethodTreeMatcher;
Expand Down Expand Up @@ -74,21 +76,38 @@ public final class CanIgnoreReturnValueSuggester extends BugChecker implements M

private static final String AUTO_VALUE = "com.google.auto.value.AutoValue";
private static final String IMMUTABLE = "com.google.errorprone.annotations.Immutable";
private static final String CRV = "com.google.errorprone.annotations.CheckReturnValue";
private static final String CIRV = "com.google.errorprone.annotations.CanIgnoreReturnValue";
private static final ImmutableSet<String> EXEMPTING_METHOD_ANNOTATIONS =
ImmutableSet.of(
CIRV,
"com.google.errorprone.annotations.CheckReturnValue",
"com.google.errorprone.refaster.annotation.AfterTemplate");

private static final Supplier<Type> PROTO_BUILDER =
VisitorState.memoize(s -> s.getTypeFromString("com.google.protobuf.MessageLite.Builder"));

private static final ImmutableSet<String> BANNED_METHOD_PREFIXES =
ImmutableSet.of("get", "is", "has", "new", "clone", "copy");

private final ImmutableSet<String> exemptingMethodAnnotations;

public CanIgnoreReturnValueSuggester(ErrorProneFlags errorProneFlags) {
this.exemptingMethodAnnotations =
errorProneFlags
.getSet("CanIgnoreReturnValue:ExemptingMethodAnnotations")
.map(
additionalAnnotations ->
Sets.union(additionalAnnotations, EXEMPTING_METHOD_ANNOTATIONS).immutableCopy())
.orElse(EXEMPTING_METHOD_ANNOTATIONS);
}

@Override
public Description matchMethod(MethodTree methodTree, VisitorState state) {
MethodSymbol methodSymbol = getSymbol(methodTree);

// if the method is already directly annotated w/ @CRV or @CIRV, bail out
if (hasAnnotation(methodSymbol, CRV, state) || hasAnnotation(methodSymbol, CIRV, state)) {
// If the method has an exempting annotation, then bail out.
if (exemptingMethodAnnotations.stream()
.anyMatch(annotation -> ASTHelpers.hasAnnotation(methodSymbol, annotation, state))) {
return Description.NO_MATCH;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,24 @@ public void constructor() {
.doTest();
}

@Test
public void refasterAfterTemplate() {
helper
.addInputLines(
"A.java",
"import com.google.errorprone.refaster.annotation.AfterTemplate;",
"class A {",
" static final class MethodLacksBeforeTemplateAnnotation {",
" @AfterTemplate",
" String after(String str) {",
" return str;",
" }",
" }",
"}")
.expectUnchanged()
.doTest();
}

@Test
public void sometimesThrows() {
helper
Expand Down Expand Up @@ -832,4 +850,26 @@ public void providesMethod_b267362954() {
.expectUnchanged()
.doTest();
}

@Test
public void exemptedByCustomAnnotation() {
helper
.addInputLines("Foo.java", "package example;", "@interface Foo {}")
.expectUnchanged()
.addInputLines(
"ExemptedByCustomAnnotation.java",
"package example;",
"public final class ExemptedByCustomAnnotation {",
" private String name;",
"",
" @Foo",
" public ExemptedByCustomAnnotation setName(String name) {",
" this.name = name;",
" return this;",
" }",
"}")
.expectUnchanged()
.setArgs("-XepOpt:CanIgnoreReturnValue:ExemptingMethodAnnotations=example.Foo")
.doTest();
}
}