Skip to content

Commit 1ca1b25

Browse files
authored
Allow suppressing nullaway on individual parameters (#1436)
1 parent d594809 commit 1ca1b25

4 files changed

Lines changed: 231 additions & 42 deletions

File tree

nullaway/src/main/java/com/uber/nullaway/NullAway.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -926,10 +926,19 @@ private Description checkParamOverriding(
926926
} else {
927927
errorTree = getTreesInstance(state).getTree(paramSymbol);
928928
}
929+
VisitorState paramState;
930+
if (memberReferenceTree != null) {
931+
// For nullability issues related to functional interfaces, the suppression should be on
932+
// the use site
933+
paramState = state;
934+
} else {
935+
TreePath path = getTreesInstance(state).getPath(paramSymbol);
936+
paramState = path != null ? state.withPath(path) : state;
937+
}
929938
return errorBuilder.createErrorDescription(
930939
new ErrorMessage(MessageTypes.WRONG_OVERRIDE_PARAM, message),
931940
buildDescription(errorTree),
932-
state,
941+
paramState,
933942
paramSymbol);
934943
}
935944
}

nullaway/src/test/java/com/uber/nullaway/SerializationTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ public class SubClass extends Super {
316316
"parameter o is @NonNull, but parameter in superclass method com.uber.Super.test(java.lang.Object) is @Nullable",
317317
"com.uber.SubClass",
318318
"test(java.lang.Object)",
319-
182,
319+
204,
320320
"com/uber/test/SubClass.java",
321321
"PARAMETER",
322322
"com.uber.SubClass",
@@ -1273,7 +1273,7 @@ public void bar(Object o) {
12731273
"parameter o is @NonNull, but parameter in superclass method com.uber.Foo.bar(java.lang.Object) is @Nullable",
12741274
"com.uber.Main$1",
12751275
"bar(java.lang.Object)",
1276-
94,
1276+
187,
12771277
"com/uber/Main.java",
12781278
"PARAMETER",
12791279
"com.uber.Main$1",

nullaway/src/test/java/com/uber/nullaway/SuppressionNameAliasesTests.java

Lines changed: 0 additions & 39 deletions
This file was deleted.
Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
package com.uber.nullaway;
2+
3+
import java.util.Arrays;
4+
import org.junit.Test;
5+
6+
public class SuppressionTests extends NullAwayTestsBase {
7+
8+
@Test
9+
public void additionalSuppressionNamesTest() {
10+
makeTestHelperWithArgs(
11+
Arrays.asList(
12+
"-d",
13+
temporaryFolder.getRoot().getAbsolutePath(),
14+
"-XepOpt:NullAway:AnnotatedPackages=com.uber",
15+
"-XepOpt:NullAway:SuppressionNameAliases=Foo,Bar"))
16+
.addSourceLines(
17+
"Test.java",
18+
"""
19+
package com.uber;
20+
import org.jspecify.annotations.Nullable;
21+
class Test {
22+
@SuppressWarnings("Foo")
23+
void foo(@Nullable Object o) {
24+
o.getClass();
25+
}
26+
@SuppressWarnings("Bar")
27+
void bar(@Nullable Object o) {
28+
o.getClass();
29+
}
30+
@SuppressWarnings("Baz")
31+
void baz(@Nullable Object o) {
32+
// BUG: Diagnostic contains: dereferenced expression o is @Nullable
33+
o.getClass();
34+
}
35+
}
36+
""")
37+
.doTest();
38+
}
39+
40+
@Test
41+
public void wrongOverrideParamSuppressionOnParameter() {
42+
defaultCompilationHelper
43+
.addSourceLines(
44+
"TestInterface.java",
45+
"""
46+
package com.uber;
47+
import javax.annotation.Nullable;
48+
public interface TestInterface {
49+
void foo(@Nullable Object param);
50+
}
51+
""")
52+
.addSourceLines(
53+
"TestImpl.java",
54+
"""
55+
package com.uber;
56+
public class TestImpl implements TestInterface {
57+
@Override
58+
public void foo(@SuppressWarnings("NullAway") Object param) {}
59+
}
60+
""")
61+
.doTest();
62+
}
63+
64+
@Test
65+
public void wrongOverrideParamSuppressionOnMethodReferenceUsage() {
66+
defaultCompilationHelper
67+
.addSourceLines(
68+
"TestInterface.java",
69+
"""
70+
package com.uber;
71+
import javax.annotation.Nullable;
72+
public interface TestInterface {
73+
void foo(@Nullable Object param);
74+
}
75+
""")
76+
.addSourceLines(
77+
"TestImpl.java",
78+
"""
79+
package com.uber;
80+
public class TestImpl {
81+
public void doFoo(Object param) {}
82+
}
83+
""")
84+
.addSourceLines(
85+
"TestDriver.java",
86+
"""
87+
package com.uber;
88+
public class TestDriver {
89+
public int bar(TestInterface param) {
90+
return 0;
91+
}
92+
public void doTest(TestImpl impl) {
93+
@SuppressWarnings("NullAway")
94+
int res = bar(impl::doFoo);
95+
}
96+
}
97+
""")
98+
.doTest();
99+
}
100+
101+
@Test
102+
public void wrongOverrideParamSuppressionOnLambda() {
103+
defaultCompilationHelper
104+
.addSourceLines(
105+
"TestInterface.java",
106+
"""
107+
package com.uber;
108+
import javax.annotation.Nullable;
109+
public interface TestInterface {
110+
void foo(@Nullable Object param);
111+
}
112+
""")
113+
.addSourceLines(
114+
"TestDriver.java",
115+
"""
116+
package com.uber;
117+
public class TestDriver {
118+
public int bar(TestInterface param) {
119+
return 0;
120+
}
121+
public void doTest() {
122+
int res = bar((@SuppressWarnings("NullAway") Object param) -> {});
123+
}
124+
}
125+
""")
126+
.doTest();
127+
}
128+
129+
@Test
130+
public void wrongOverrideParamNoSuppression() {
131+
defaultCompilationHelper
132+
.addSourceLines(
133+
"TestInterface.java",
134+
"""
135+
package com.uber;
136+
import javax.annotation.Nullable;
137+
public interface TestInterface {
138+
void foo(@Nullable Object param);
139+
}
140+
""")
141+
.addSourceLines(
142+
"TestImpl.java",
143+
"""
144+
package com.uber;
145+
public class TestImpl implements TestInterface {
146+
@Override
147+
// BUG: Diagnostic contains: parameter param is @NonNull, but parameter in superclass method
148+
public void foo(Object param) {}
149+
}
150+
""")
151+
.doTest();
152+
}
153+
154+
@Test
155+
public void wrongOverrideParamOnMethodReferenceUsageNoSuppression() {
156+
defaultCompilationHelper
157+
.addSourceLines(
158+
"TestInterface.java",
159+
"""
160+
package com.uber;
161+
import javax.annotation.Nullable;
162+
public interface TestInterface {
163+
void foo(@Nullable Object param);
164+
}
165+
""")
166+
.addSourceLines(
167+
"TestImpl.java",
168+
"""
169+
package com.uber;
170+
public class TestImpl {
171+
public void doFoo(Object param) {}
172+
}
173+
""")
174+
.addSourceLines(
175+
"TestDriver.java",
176+
"""
177+
package com.uber;
178+
public class TestDriver {
179+
public int bar(TestInterface param) {
180+
return 0;
181+
}
182+
public void doTest(TestImpl impl) {
183+
// BUG: Diagnostic contains: parameter param of referenced method is @NonNull, but parameter in functional interface method
184+
int res = bar(impl::doFoo);
185+
}
186+
}
187+
""")
188+
.doTest();
189+
}
190+
191+
@Test
192+
public void wrongOverrideParamOnLambdaNoSuppression() {
193+
defaultCompilationHelper
194+
.addSourceLines(
195+
"TestInterface.java",
196+
"""
197+
package com.uber;
198+
import javax.annotation.Nullable;
199+
public interface TestInterface {
200+
void foo(@Nullable Object param);
201+
}
202+
""")
203+
.addSourceLines(
204+
"TestDriver.java",
205+
"""
206+
package com.uber;
207+
public class TestDriver {
208+
public int bar(TestInterface param) {
209+
return 0;
210+
}
211+
public void doTest() {
212+
// BUG: Diagnostic contains: parameter param is @NonNull, but parameter in functional interface method
213+
int res = bar((Object param) -> {});
214+
}
215+
}
216+
""")
217+
.doTest();
218+
}
219+
}

0 commit comments

Comments
 (0)