Skip to content

Commit

Permalink
Update ASTHelpers.hasDirectAnnotationWithSimpleName to handle `TYPE…
Browse files Browse the repository at this point in the history
…_USE` annotations on field types and method return types

This allows `ProvidesNull` to handle `TYPE_USE` `@Nullable` annotations.

Startblock:
  unknown commit is submitted
PiperOrigin-RevId: 583055698
  • Loading branch information
cushon authored and Error Prone Team committed Nov 16, 2023
1 parent 0b70afc commit aa6e3e7
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 14 deletions.
43 changes: 33 additions & 10 deletions check_api/src/main/java/com/google/errorprone/util/ASTHelpers.java
Original file line number Diff line number Diff line change
Expand Up @@ -991,20 +991,43 @@ private static Set<Name> directAnnotationsAmong(
}

/**
* Check for the presence of an annotation with a specific simple name directly on this symbol.
* Does *not* consider annotation inheritance.
* Check for the presence of an annotation with the given simple name directly on this symbol or
* its type. (If the given symbol is a method symbol, the type searched for annotations is its
* return type.)
*
* @param sym the symbol to check for the presence of the annotation
* @param simpleName the simple name of the annotation to look for, e.g. "Nullable" or
* "CheckReturnValue"
* <p>This method looks only a annotations that are directly present. It does <b>not</b> consider
* annotation inheritance (see JLS 9.6.4.3).
*/
public static boolean hasDirectAnnotationWithSimpleName(Symbol sym, String simpleName) {
for (AnnotationMirror annotation : sym.getAnnotationMirrors()) {
if (annotation.getAnnotationType().asElement().getSimpleName().contentEquals(simpleName)) {
return true;
}
if (sym instanceof MethodSymbol) {
return hasDirectAnnotationWithSimpleName((MethodSymbol) sym, simpleName);
}
return false;
if (sym instanceof VarSymbol) {
return hasDirectAnnotationWithSimpleName((VarSymbol) sym, simpleName);
}
return hasDirectAnnotationWithSimpleName(sym.getAnnotationMirrors().stream(), simpleName);
}

public static boolean hasDirectAnnotationWithSimpleName(MethodSymbol sym, String simpleName) {
return hasDirectAnnotationWithSimpleName(
Streams.concat(
sym.getAnnotationMirrors().stream(),
sym.getReturnType().getAnnotationMirrors().stream()),
simpleName);
}

public static boolean hasDirectAnnotationWithSimpleName(VarSymbol sym, String simpleName) {
return hasDirectAnnotationWithSimpleName(
Streams.concat(
sym.getAnnotationMirrors().stream(), sym.asType().getAnnotationMirrors().stream()),
simpleName);
}

private static boolean hasDirectAnnotationWithSimpleName(
Stream<? extends AnnotationMirror> annotations, String simpleName) {
return annotations.anyMatch(
annotation ->
annotation.getAnnotationType().asElement().getSimpleName().contentEquals(simpleName));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,6 @@ public void hasTypeUseNullableOnMethod() {
" @Provides",
" @Nullable",
" public Object providesObject() {",
" // BUG: Diagnostic contains: Did you mean '@Nullable' or 'throw new"
+ " RuntimeException();'",
" return null;",
" }",
"}")
Expand All @@ -108,8 +106,6 @@ public void hasTypeUseNullableOnReturnType() {
"public class Test {",
" @Provides",
" public @Nullable Object providesObject() {",
" // BUG: Diagnostic contains: Did you mean '@Nullable' or 'throw new"
+ " RuntimeException();'",
" return null;",
" }",
"}")
Expand Down Expand Up @@ -189,4 +185,26 @@ public void returnWithNoExpression() {
"}")
.doTest();
}

@Test
public void hasOtherTypeUseNullable() {
compilationHelper
.addSourceLines(
"Nullable.java",
"import static java.lang.annotation.ElementType.TYPE_USE;",
"import java.lang.annotation.Target;",
"@Target(TYPE_USE)",
"public @interface Nullable {}")
.addSourceLines(
"Test.java",
"import dagger.Provides;",
"public class Test {",
" @Provides",
" @Nullable",
" public Object providesObject() {",
" return null;",
" }",
"}")
.doTest();
}
}

0 comments on commit aa6e3e7

Please sign in to comment.