-
Notifications
You must be signed in to change notification settings - Fork 295
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
Partial handling for restrictive annotations on varargs in unannotated code #1029
Changes from 10 commits
e0be617
2309531
fcfeb94
14ae632
18a7002
c644768
e5d7d1b
4f07f82
e13dc58
e312e44
32e9aa2
7330a20
118dc17
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -200,7 +200,8 @@ public void testSkipJetbrainsNotNullOnVarArgsFromThirdPartyJars() { | |
" ThirdParty.takesNullableVarargs(o1);", // Empty var args passed | ||
" ThirdParty.takesNullableVarargs(o1, o4);", | ||
" ThirdParty.takesNullableVarargs(o1, (Object) null);", | ||
" // BUG: Diagnostic contains: passing @Nullable parameter '(Object[]) null' where @NonNull", | ||
" // No error: we require a type-use annotation for nullability of the varargs array itself", | ||
// TODO should we preserve the old behavior in legacy mode? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @lazaroclapp with this change, we no longer detect an error when passing a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think without a coordinated change on Unfortunately, Java code interfacing with Kotlin code is a big portion of what we will see in Android for the foreseeable future, so There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're right; it looks like for now |
||
" ThirdParty.takesNullableVarargs(o1, (Object[]) null);", | ||
" // BUG: Diagnostic contains: passing @Nullable parameter 'o4' where @NonNull", | ||
" ThirdParty.takesNullableVarargs(o4);", // First arg is not varargs. | ||
|
@@ -416,6 +417,85 @@ public void varargsPassArrayAndOtherArgs() { | |
.doTest(); | ||
} | ||
|
||
@Test | ||
public void testVarargsNullArrayUnannotated() { | ||
defaultCompilationHelper | ||
.addSourceLines( | ||
"Unannotated.java", | ||
"package foo.unannotated;", | ||
"public class Unannotated {", | ||
" public static void takesVarargs(Object... args) {}", | ||
"}") | ||
.addSourceLines( | ||
"Test.java", | ||
"package com.uber;", | ||
"import foo.unannotated.Unannotated;", | ||
"public class Test {", | ||
" public void test() {", | ||
" Object[] x = null;", | ||
" Unannotated.takesVarargs(x);", | ||
" }", | ||
"}") | ||
.doTest(); | ||
} | ||
|
||
/** | ||
* This test is a WIP for restrictive annotations on varargs. More assertions still need to be | ||
* written, and more support needs to be implemented. | ||
*/ | ||
@Test | ||
public void testVarargsRestrictive() { | ||
makeTestHelperWithArgs( | ||
Arrays.asList( | ||
"-d", | ||
temporaryFolder.getRoot().getAbsolutePath(), | ||
"-XepOpt:NullAway:AnnotatedPackages=com.uber", | ||
"-XepOpt:NullAway:LegacyAnnotationLocations=true", | ||
"-XepOpt:NullAway:AcknowledgeRestrictiveAnnotations=true")) | ||
.addSourceLines( | ||
"NonNull.java", | ||
"package com.uber.both;", | ||
"import java.lang.annotation.ElementType;", | ||
"import java.lang.annotation.Target;", | ||
"@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE, ElementType.TYPE_USE})", | ||
"public @interface NonNull {}") | ||
.addSourceLines( | ||
"Unannotated.java", | ||
"package foo.unannotated;", | ||
"public class Unannotated {", | ||
" public static void takesVarargsDeclaration(@javax.annotation.Nonnull Object... args) {}", | ||
" public static void takesVarargsTypeUseOnArray(Object @org.jspecify.annotations.NonNull... args) {}", | ||
" public static void takesVarargsTypeUseOnElements(@org.jspecify.annotations.NonNull Object... args) {}", | ||
" public static void takesVarargsTypeUseOnBoth(@org.jspecify.annotations.NonNull Object @org.jspecify.annotations.NonNull... args) {}", | ||
" public static void takesVarargsBothOnArray(Object @com.uber.both.NonNull... args) {}", | ||
" public static void takesVarargsBothOnElements(@com.uber.both.NonNull Object... args) {}", | ||
" public static void takesVarargsBothOnBoth(@com.uber.both.NonNull Object @com.uber.both.NonNull... args) {}", | ||
"}") | ||
.addSourceLines( | ||
"Test.java", | ||
"package com.uber;", | ||
"import foo.unannotated.Unannotated;", | ||
"public class Test {", | ||
" public void testDeclaration() {", | ||
" Object x = null;", | ||
" Object[] y = null;", | ||
" // BUG: Diagnostic contains: passing @Nullable parameter 'x'", | ||
" Unannotated.takesVarargsDeclaration(x);", | ||
" // BUG: Diagnostic contains: passing @Nullable parameter 'y'", | ||
" Unannotated.takesVarargsDeclaration(y);", | ||
" }", | ||
" public void testTypeUseOnArray() {", | ||
" Object x = null;", | ||
" Object[] y = null;", | ||
" // BUG: Diagnostic contains: passing @Nullable parameter 'x'", | ||
" Unannotated.takesVarargsTypeUseOnArray(x);", | ||
" // BUG: Diagnostic contains: passing @Nullable parameter 'y'", | ||
" Unannotated.takesVarargsTypeUseOnArray(y);", | ||
" }", | ||
"}") | ||
.doTest(); | ||
} | ||
|
||
private CompilationTestHelper makeHelper() { | ||
return makeTestHelperWithArgs( | ||
Arrays.asList( | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is codecov correct here that we never test the case where this method returns
false
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is correct. We should get coverage of this line when we add logic to process restrictive
@NonNull
annotations on array elements in positions other than the varargs position, which we will do in a follow up.