Skip to content

Commit

Permalink
Fix for querying for generated code w/ .class expressions. (#655)
Browse files Browse the repository at this point in the history
Follow up to #654, very similar situation, but on a different `CodeAnnotationInfo` (i.e `isGenerated`).

This version of the issue only shows up under `-XepOpt:NullAway:TreatGeneratedAsUnannotated=true` so it wasn't caught by our earlier test (or our internal Android codebase).
  • Loading branch information
lazaroclapp authored Sep 13, 2022
1 parent de1a12b commit 3d09158
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 3 deletions.
13 changes: 11 additions & 2 deletions nullaway/src/main/java/com/uber/nullaway/CodeAnnotationInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,17 @@ private static boolean fromAnnotatedPackage(
* {@code @Generated}; false otherwise
*/
public boolean isGenerated(Symbol symbol, Config config) {
Symbol.ClassSymbol outermostClassSymbol =
get(castToNonNull(ASTHelpers.enclosingClass(symbol)), config).outermostClassSymbol;
Symbol.ClassSymbol classSymbol = ASTHelpers.enclosingClass(symbol);
if (classSymbol == null) {
Preconditions.checkArgument(
isClassFieldOfPrimitiveType(
symbol), // One known case where this can happen: int.class, void.class, etc.
String.format(
"Unexpected symbol passed to CodeAnnotationInfo.isGenerated(...) with null enclosing class: %s",
symbol));
return false;
}
Symbol.ClassSymbol outermostClassSymbol = get(classSymbol, config).outermostClassSymbol;
return ASTHelpers.hasDirectAnnotationWithSimpleName(outermostClassSymbol, "Generated");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1049,7 +1049,7 @@ public void nullMarkedStaticImports() {
}

@Test
public void dotClassSanityTest() {
public void dotClassSanityTest1() {
// Check that we do not crash while determining the nullmarked-ness of primitive.class (e.g.
// int.class)
makeTestHelperWithArgs(
Expand All @@ -1064,6 +1064,7 @@ public void dotClassSanityTest() {
"package com.uber;",
"import com.example.jspecify.future.annotations.NullMarked;",
"import org.jspecify.nullness.Nullable;",
"import java.lang.reflect.Field;",
"@NullMarked",
"public class Test {",
" public void takesClass(Class c) {",
Expand All @@ -1078,6 +1079,54 @@ public void dotClassSanityTest() {
" // NEEDED TO TRIGGER DATAFLOW:",
" return flag ? Test.class : new Object();",
" }",
" public boolean test2(Field field) {",
" if (field.getType() == int.class || field.getType() == Integer.class) {",
" return true;",
" }",
" return false;",
" }",
"}")
.doTest();
}

@Test
public void dotClassSanityTest2() {
// Check that we do not crash while determining the nullmarked-ness of primitive.class (e.g.
// int.class)
makeTestHelperWithArgs(
Arrays.asList(
"-d",
temporaryFolder.getRoot().getAbsolutePath(),
// Flag is required for now, but might no longer be need with @NullMarked!
"-XepOpt:NullAway:AnnotatedPackages=com.uber.dontcare",
"-XepOpt:NullAway:AcknowledgeRestrictiveAnnotations=true",
"-XepOpt:NullAway:TreatGeneratedAsUnannotated=true"))
.addSourceLines(
"Test.java",
"package com.uber;",
"import com.example.jspecify.future.annotations.NullMarked;",
"import org.jspecify.nullness.Nullable;",
"import java.lang.reflect.Field;",
"@NullMarked",
"public class Test {",
" public void takesClass(Class c) {",
" }",
" public Object test(boolean flag) {",
" takesClass(Test.class);",
" takesClass(String.class);",
" takesClass(int.class);",
" takesClass(boolean.class);",
" takesClass(float.class);",
" takesClass(void.class);",
" // NEEDED TO TRIGGER DATAFLOW:",
" return flag ? Test.class : new Object();",
" }",
" public boolean test2(Field field) {",
" if (field.getType() == int.class || field.getType() == Integer.class) {",
" return true;",
" }",
" return false;",
" }",
"}")
.doTest();
}
Expand Down

0 comments on commit 3d09158

Please sign in to comment.