Added
Link Here
|
1 |
/******************************************************************************* |
2 |
* Copyright (c) 2010 GK Software AG and others. |
3 |
* All rights reserved. This program and the accompanying materials |
4 |
* are made available under the terms of the Eclipse Public License v1.0 |
5 |
* which accompanies this distribution, and is available at |
6 |
* http://www.eclipse.org/legal/epl-v10.html |
7 |
* |
8 |
* Contributors: |
9 |
* Stephan Herrmann <sherrmann@gk-software.com> - initial API and implementation |
10 |
*******************************************************************************/ |
11 |
package org.eclipse.jdt.core.tests.compiler.regression; |
12 |
|
13 |
import java.util.Map; |
14 |
|
15 |
import junit.framework.Test; |
16 |
|
17 |
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; |
18 |
|
19 |
public class NullAnnotationTest extends AbstractComparableTest { |
20 |
|
21 |
public NullAnnotationTest(String name) { |
22 |
super(name); |
23 |
} |
24 |
|
25 |
// Static initializer to specify tests subset using TESTS_* static variables |
26 |
// All specified tests which does not belong to the class are skipped... |
27 |
// Only the highest compliance level is run; add the VM argument |
28 |
// -Dcompliance=1.4 (for example) to lower it if needed |
29 |
static { |
30 |
// TESTS_NAMES = new String[] { "test_nonnull_paramter_005" }; |
31 |
// TESTS_NUMBERS = new int[] { 561 }; |
32 |
// TESTS_RANGE = new int[] { 1, 2049 }; |
33 |
} |
34 |
|
35 |
public static Test suite() { |
36 |
return buildComparableTestSuite(testClass()); |
37 |
} |
38 |
|
39 |
public static Class testClass() { |
40 |
return NullAnnotationTest.class; |
41 |
} |
42 |
|
43 |
// Conditionally augment problem detection settings |
44 |
static boolean setNullRelatedOptions = true; |
45 |
protected Map getCompilerOptions() { |
46 |
Map defaultOptions = super.getCompilerOptions(); |
47 |
if (setNullRelatedOptions) { |
48 |
defaultOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR); |
49 |
defaultOptions.put(CompilerOptions.OPTION_ReportPotentialNullReference, CompilerOptions.ERROR); |
50 |
defaultOptions.put(CompilerOptions.OPTION_ReportRedundantNullCheck, CompilerOptions.ERROR); |
51 |
defaultOptions.put(CompilerOptions.OPTION_ReportRawTypeReference, CompilerOptions.IGNORE); |
52 |
defaultOptions.put(CompilerOptions.OPTION_IncludeNullInfoFromAsserts, CompilerOptions.ENABLED); |
53 |
|
54 |
// leave new options at these defaults: |
55 |
// defaultOptions.put(CompilerOptions.OPTION_ReportNullContractViolation, CompilerOptions.ERROR); |
56 |
// defaultOptions.put(CompilerOptions.OPTION_ReportPotentialNullContractViolation, CompilerOptions.WARNING); |
57 |
// defaultOptions.put(CompilerOptions.OPTION_ReportNullContractInsufficientInfo, CompilerOptions.WARNING); |
58 |
|
59 |
defaultOptions.put(CompilerOptions.OPTION_NullableAnnotationName, "org.eclipse.jdt.annotation.Nullable"); |
60 |
defaultOptions.put(CompilerOptions.OPTION_NonNullAnnotationName, "org.eclipse.jdt.annotation.NonNull"); |
61 |
defaultOptions.put(CompilerOptions.OPTION_EmulateNullAnnotationTypes, CompilerOptions.ENABLED); |
62 |
defaultOptions.put(CompilerOptions.OPTION_DefaultImportNullAnnotationTypes, CompilerOptions.ENABLED); |
63 |
} |
64 |
return defaultOptions; |
65 |
} |
66 |
|
67 |
// a non-null argument is checked for null |
68 |
public void test_nonnull_parameter_001() { |
69 |
runNegativeTest( |
70 |
new String[] { |
71 |
"X.java", |
72 |
"public class X {\n" + |
73 |
" void foo(@NonNull Object o) {\n" + |
74 |
" if (o != null)\n" + |
75 |
" System.out.print(o.toString());\n" + |
76 |
" }\n" + |
77 |
"}\n"}, |
78 |
"----------\n" + |
79 |
"1. ERROR in X.java (at line 3)\n" + |
80 |
" if (o != null)\n" + |
81 |
" ^\n" + |
82 |
"Redundant null check: The variable o cannot be null at this location\n" + |
83 |
"----------\n", |
84 |
JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); |
85 |
} |
86 |
// a non-null argument is dereferenced without a check |
87 |
public void test_nonnull_parameter_002() { |
88 |
runConformTest( |
89 |
new String[] { |
90 |
"X.java", |
91 |
"public class X {\n" + |
92 |
" void foo(@NonNull Object o) {\n" + |
93 |
" System.out.print(o.toString());\n" + |
94 |
" }\n" + |
95 |
" public static void main(String... args) {\n" + |
96 |
" new X().foo(\"OK\");\n" + |
97 |
" }\n" + |
98 |
"}\n"}, |
99 |
"OK"); |
100 |
} |
101 |
// a nullable argument is dereferenced without a check |
102 |
public void test_nullable_paramter_003() { |
103 |
runNegativeTest( |
104 |
new String[] { |
105 |
"X.java", |
106 |
"public class X {\n" + |
107 |
" void foo(@Nullable Object o) {\n" + |
108 |
" System.out.print(o.toString());\n" + |
109 |
" }\n" + |
110 |
"}\n"}, |
111 |
"----------\n" + |
112 |
"1. ERROR in X.java (at line 3)\n" + |
113 |
" System.out.print(o.toString());\n" + |
114 |
" ^\n" + |
115 |
"Potential null pointer access: The variable o may be null at this location\n" + |
116 |
"----------\n", |
117 |
JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); |
118 |
} |
119 |
// passing null to nonnull parameter |
120 |
public void test_nonnull_paramter_001() { |
121 |
runNegativeTest( |
122 |
new String[] { |
123 |
"X.java", |
124 |
"public class X {\n" + |
125 |
" void foo(@NonNull Object o) {\n" + |
126 |
" System.out.print(o.toString());\n" + |
127 |
" }\n" + |
128 |
" void bar() {\n" + |
129 |
" foo(null);\n" + |
130 |
" }\n" + |
131 |
"}\n"}, |
132 |
"----------\n" + |
133 |
"1. ERROR in X.java (at line 6)\n" + |
134 |
" foo(null);\n" + |
135 |
" ^^^^\n" + |
136 |
"Null contract violation: passing null to a parameter declared as @NonNull.\n" + |
137 |
"----------\n", |
138 |
JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); |
139 |
} |
140 |
// passing potential null to nonnull parameter |
141 |
public void test_nonnull_paramter_002() { |
142 |
runConformTest( |
143 |
new String[] { |
144 |
"Lib.java", |
145 |
"public class Lib {\n" + |
146 |
" void setObject(@NonNull Object o) { }\n" + |
147 |
"}\n" |
148 |
}); |
149 |
runConformTest( |
150 |
false /* flush output directory */, |
151 |
new String[] { |
152 |
"X.java", |
153 |
"public class X {\n" + |
154 |
" void bar(Lib l, boolean b) {\n" + |
155 |
" Object o = null;\n" + |
156 |
" if (b) o = new Object();\n" + |
157 |
" l.setObject(o);\n" + |
158 |
" }\n" + |
159 |
"}\n"}, |
160 |
null /* no class libraries */, |
161 |
null /* no custom options */, |
162 |
"----------\n" + |
163 |
"1. WARNING in X.java (at line 5)\n" + |
164 |
" l.setObject(o);\n" + |
165 |
" ^\n" + |
166 |
"Potential null contract violation: potentially passing null to a parameter declared as @NonNull.\n" + |
167 |
"----------\n", |
168 |
"",/* expected output */ |
169 |
"",/* expected error */ |
170 |
JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); |
171 |
} |
172 |
// passing unknown value to nonnull parameter |
173 |
public void test_nonnull_paramter_003() { |
174 |
runConformTest( |
175 |
new String[] { |
176 |
"Lib.java", |
177 |
"public class Lib {\n" + |
178 |
" void setObject(@NonNull Object o) { }\n" + |
179 |
"}\n" |
180 |
}); |
181 |
runConformTest( |
182 |
false /* flush output directory */, |
183 |
new String[] { |
184 |
"X.java", |
185 |
"public class X {\n" + |
186 |
" void bar(Lib l, Object o) {\n" + |
187 |
" l.setObject(o);\n" + |
188 |
" }\n" + |
189 |
"}\n"}, |
190 |
null /* no class libraries */, |
191 |
null /* no custom options */, |
192 |
"----------\n" + |
193 |
"1. WARNING in X.java (at line 3)\n" + |
194 |
" l.setObject(o);\n" + |
195 |
" ^\n" + |
196 |
"Potential null contract violation: insufficient nullness information regarding a value that is passed to a parameter declared as @NonNull.\n" + |
197 |
"----------\n", |
198 |
"",/* expected output */ |
199 |
"",/* expected error */ |
200 |
JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); |
201 |
} |
202 |
// a method tries to tighten the null contract, super declares parameter as @Nullable |
203 |
public void test_nonnull_paramter_004() { |
204 |
runConformTest( |
205 |
new String[] { |
206 |
"Lib.java", |
207 |
"public class Lib {\n" + |
208 |
" void foo(@Nullable Object o) { }\n" + |
209 |
"}\n" |
210 |
}); |
211 |
runNegativeTest( |
212 |
false /* flush output directory */, |
213 |
new String[] { |
214 |
"X.java", |
215 |
"public class X extends Lib {\n" + |
216 |
" @Override\n" + |
217 |
" void foo(@NonNull Object o) { System.out.print(o.toString()); }\n" + |
218 |
"}\n" |
219 |
}, |
220 |
// compiler options |
221 |
null /* no class libraries */, |
222 |
null /* no custom options */, |
223 |
"----------\n" + |
224 |
"1. ERROR in X.java (at line 3)\n" + |
225 |
" void foo(@NonNull Object o) { System.out.print(o.toString()); }\n" + |
226 |
" ^\n" + |
227 |
"Cannot tighten null contract for parameter, inherited method from Lib declares the parameter as @Nullable.\n" + |
228 |
"----------\n", |
229 |
JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); |
230 |
} |
231 |
// a method body fails to handle the inherited null contract, super declares parameter as @Nullable |
232 |
public void test_nonnull_paramter_005() { |
233 |
runConformTest( |
234 |
new String[] { |
235 |
"Lib.java", |
236 |
"public class Lib {\n" + |
237 |
" void foo(@Nullable Object o) { }\n" + |
238 |
"}\n" |
239 |
}); |
240 |
runNegativeTest( |
241 |
false /* flush output directory */, |
242 |
new String[] { |
243 |
"X.java", |
244 |
"public class X extends Lib {\n" + |
245 |
" @Override\n" + |
246 |
" void foo(Object o) {\n" + |
247 |
" System.out.print(o.toString());\n" + |
248 |
" }\n" + |
249 |
"}\n" |
250 |
}, |
251 |
// compiler options |
252 |
null /* no class libraries */, |
253 |
null /* no custom options */, |
254 |
"----------\n" + |
255 |
"1. ERROR in X.java (at line 4)\n" + |
256 |
" System.out.print(o.toString());\n" + |
257 |
" ^\n" + |
258 |
"Potential null pointer access: The variable o may be null at this location\n" + |
259 |
"----------\n", |
260 |
JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); |
261 |
} |
262 |
|
263 |
// a nullable return value is dereferenced without a check |
264 |
public void test_nullable_return_001() { |
265 |
runNegativeTest( |
266 |
new String[] { |
267 |
"X.java", |
268 |
"public class X {\n" + |
269 |
" @Nullable Object getObject() { return null; }\n" + |
270 |
" void foo() {\n" + |
271 |
" Object o = getObject();\n" + |
272 |
" System.out.print(o.toString());\n" + |
273 |
" }\n" + |
274 |
"}\n" |
275 |
}, |
276 |
"----------\n" + |
277 |
"1. ERROR in X.java (at line 5)\n" + |
278 |
" System.out.print(o.toString());\n" + |
279 |
" ^\n" + |
280 |
"Potential null pointer access: The variable o may be null at this location\n" + |
281 |
"----------\n", |
282 |
JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); |
283 |
} |
284 |
// a nullable return value is dereferenced without a check, method is read from .class file |
285 |
public void test_nullable_return_002() { |
286 |
runConformTest( |
287 |
new String[] { |
288 |
"Lib.java", |
289 |
"public class Lib {\n" + |
290 |
" @Nullable Object getObject() { return null; }\n" + |
291 |
"}\n" |
292 |
}); |
293 |
runNegativeTest( |
294 |
false /* flush output directory */, |
295 |
new String[] { |
296 |
"X.java", |
297 |
"public class X {\n" + |
298 |
" void foo(Lib l) {\n" + |
299 |
" Object o = l.getObject();\n" + |
300 |
" System.out.print(o.toString());\n" + |
301 |
" }\n" + |
302 |
"}\n" |
303 |
}, |
304 |
// compiler options |
305 |
null /* no class libraries */, |
306 |
null /* no custom options */, |
307 |
"----------\n" + |
308 |
"1. ERROR in X.java (at line 4)\n" + |
309 |
" System.out.print(o.toString());\n" + |
310 |
" ^\n" + |
311 |
"Potential null pointer access: The variable o may be null at this location\n" + |
312 |
"----------\n", |
313 |
JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); |
314 |
} |
315 |
// a non-null return value is checked for null, method is read from .class file |
316 |
public void test_nonnull_return_001() { |
317 |
runConformTest( |
318 |
new String[] { |
319 |
"Lib.java", |
320 |
"public class Lib {\n" + |
321 |
" @NonNull Object getObject() { return new Object(); }\n" + |
322 |
"}\n" |
323 |
}); |
324 |
runNegativeTest( |
325 |
false /* flush output directory */, |
326 |
new String[] { |
327 |
"X.java", |
328 |
"public class X {\n" + |
329 |
" void foo(Lib l) {\n" + |
330 |
" Object o = l.getObject();\n" + |
331 |
" if (o != null)\n" + |
332 |
" System.out.print(o.toString());\n" + |
333 |
" }\n" + |
334 |
"}\n" |
335 |
}, |
336 |
// compiler options |
337 |
null /* no class libraries */, |
338 |
null /* no custom options */, |
339 |
"----------\n" + |
340 |
"1. ERROR in X.java (at line 4)\n" + |
341 |
" if (o != null)\n" + |
342 |
" ^\n" + |
343 |
"Redundant null check: The variable o cannot be null at this location\n" + |
344 |
"----------\n", |
345 |
JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); |
346 |
} |
347 |
// a non-null method returns null |
348 |
public void test_nonnull_return_003() { |
349 |
runNegativeTest( |
350 |
new String[] { |
351 |
"X.java", |
352 |
"public class X {\n" + |
353 |
" @NonNull Object getObject(boolean b) {\n" + |
354 |
" if (b)\n" + |
355 |
" return null;\n" + // definite contract violation despite enclosing "if" |
356 |
" return new Object();\n" + |
357 |
" }\n" + |
358 |
"}\n" |
359 |
}, |
360 |
"----------\n" + |
361 |
"1. ERROR in X.java (at line 4)\n" + |
362 |
" return null;\n" + |
363 |
" ^^^^^^^^^^^^\n" + |
364 |
"Null contract violation: returning null from a method declared as @NonNull.\n" + |
365 |
"----------\n", |
366 |
JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); |
367 |
} |
368 |
// a non-null method potentially returns null |
369 |
public void test_nonnull_return_004() { |
370 |
runNegativeTest( |
371 |
new String[] { |
372 |
"X.java", |
373 |
"public class X {\n" + |
374 |
" @NonNull Object getObject(@Nullable Object o) {\n" + |
375 |
" return o;\n" + // potential contract violation because 'o' is only potentially null |
376 |
" }\n" + |
377 |
"}\n" |
378 |
}, |
379 |
"----------\n" + |
380 |
"1. WARNING in X.java (at line 3)\n" + |
381 |
" return o;\n" + |
382 |
" ^^^^^^^^^\n" + |
383 |
"Potential null contract violation: return value can be null but method is declared as @NonNull.\n" + |
384 |
"----------\n"); |
385 |
} |
386 |
// a non-null method returns its non-null argument |
387 |
public void test_nonnull_return_005() { |
388 |
Map customOptions = getCompilerOptions(); |
389 |
customOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR); |
390 |
runConformTest( |
391 |
new String[] { |
392 |
"X.java", |
393 |
"public class X {\n" + |
394 |
" @NonNull Object getObject(@NonNull Object o) {\n" + |
395 |
" return o;\n" + |
396 |
" }\n" + |
397 |
"}\n" |
398 |
}, |
399 |
"", |
400 |
null/*classLibs*/, |
401 |
true/*shouldFlushOutputDirectory*/, |
402 |
null/*vmArguments*/, |
403 |
customOptions, |
404 |
null/*compilerRequestor*/); |
405 |
} |
406 |
//a non-null method has insufficient nullness info for its return value |
407 |
public void test_nonnull_return_006() { |
408 |
runNegativeTest( |
409 |
new String[] { |
410 |
"X.java", |
411 |
"public class X {\n" + |
412 |
" @NonNull Object getObject(Object o) {\n" + |
413 |
" return o;\n" + |
414 |
" }\n" + |
415 |
"}\n" |
416 |
}, |
417 |
"----------\n" + |
418 |
"1. WARNING in X.java (at line 3)\n" + |
419 |
" return o;\n" + |
420 |
" ^^^^^^^^^\n" + |
421 |
"Potential null contract violation: insufficient nullness information regarding return value while the method is declared as @NonNull.\n" + |
422 |
"----------\n"); |
423 |
} |
424 |
// a non-null method returns a non-null return of another method, mixed use of fully qualified name / explicit import |
425 |
public void test_nonnull_return_007() { |
426 |
Map customOptions = getCompilerOptions(); |
427 |
customOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR); |
428 |
customOptions.put(CompilerOptions.OPTION_NullableAnnotationName, "org.foo.Nullable"); |
429 |
customOptions.put(CompilerOptions.OPTION_NonNullAnnotationName, "org.foo.NonNull"); |
430 |
customOptions.put(CompilerOptions.OPTION_DefaultImportNullAnnotationTypes, CompilerOptions.DISABLED); |
431 |
runConformTest( |
432 |
new String[] { |
433 |
"Lib.java", |
434 |
"public class Lib {\n" + |
435 |
" @org.foo.NonNull Object getObject() { return new Object(); }\n" + // FQN |
436 |
"}\n", |
437 |
"X.java", |
438 |
"import org.foo.NonNull;\n" + // explicit import |
439 |
"public class X {\n" + |
440 |
" @NonNull Object getObject(@NonNull Lib l) {\n" + |
441 |
" return l.getObject();\n" + |
442 |
" }\n" + |
443 |
"}\n" |
444 |
}, |
445 |
"", |
446 |
null/*classLibs*/, |
447 |
true/*shouldFlushOutputDirectory*/, |
448 |
null/*vmArguments*/, |
449 |
customOptions, |
450 |
null/*compilerRequestor*/); |
451 |
} |
452 |
// a non-null method returns a non-null return of another method, use of explicit imports throughout |
453 |
public void test_nonnull_return_008() { |
454 |
Map customOptions = getCompilerOptions(); |
455 |
customOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR); |
456 |
customOptions.put(CompilerOptions.OPTION_NullableAnnotationName, "org.foo.Nullable"); |
457 |
customOptions.put(CompilerOptions.OPTION_NonNullAnnotationName, "org.foo.NonNull"); |
458 |
customOptions.put(CompilerOptions.OPTION_DefaultImportNullAnnotationTypes, CompilerOptions.DISABLED); |
459 |
runConformTest( |
460 |
new String[] { |
461 |
"Lib.java", |
462 |
"import org.foo.NonNull;\n" + |
463 |
"public class Lib {\n" + |
464 |
" @NonNull Object getObject() { return new Object(); }\n" + |
465 |
"}\n", |
466 |
"X.java", |
467 |
"import org.foo.NonNull;\n" + |
468 |
"public class X {\n" + |
469 |
" @NonNull Object getObject(@NonNull Lib l) {\n" + |
470 |
" Object o = l.getObject();" + |
471 |
" return o;\n" + |
472 |
" }\n" + |
473 |
"}\n" |
474 |
}, |
475 |
"", |
476 |
null/*classLibs*/, |
477 |
true/*shouldFlushOutputDirectory*/, |
478 |
null/*vmArguments*/, |
479 |
customOptions, |
480 |
null/*compilerRequestor*/); |
481 |
} |
482 |
// a non-null method returns a non-null return of another method, default import plus explicit ones |
483 |
public void test_nonnull_return_009() { |
484 |
Map customOptions = getCompilerOptions(); |
485 |
customOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR); |
486 |
customOptions.put(CompilerOptions.OPTION_NullableAnnotationName, "org.foo.Nullable"); |
487 |
customOptions.put(CompilerOptions.OPTION_NonNullAnnotationName, "org.foo.NonNull"); |
488 |
customOptions.put(CompilerOptions.OPTION_DefaultImportNullAnnotationTypes, CompilerOptions.ENABLED); |
489 |
runConformTest( |
490 |
new String[] { |
491 |
"libpack/Lib.java", |
492 |
"package libpack;\n" + |
493 |
"public class Lib {\n" + |
494 |
" public @NonNull Object getObject() { return new Object(); }\n" + |
495 |
"}\n", |
496 |
"X.java", |
497 |
"import libpack.Lib;\n" + |
498 |
"public class X {\n" + |
499 |
" @NonNull Object getObject(@NonNull Lib l) {\n" + |
500 |
" return l.getObject();\n" + |
501 |
" }\n" + |
502 |
"}\n" |
503 |
}, |
504 |
"", |
505 |
null/*classLibs*/, |
506 |
true/*shouldFlushOutputDirectory*/, |
507 |
null/*vmArguments*/, |
508 |
customOptions, |
509 |
null/*compilerRequestor*/); |
510 |
} |
511 |
// a non-null method returns a non-null return of another method, default import but unspecified annotation names |
512 |
public void test_nonnull_return_010() { |
513 |
Map customOptions = getCompilerOptions(); |
514 |
customOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR); |
515 |
customOptions.put(CompilerOptions.OPTION_NullableAnnotationName, null); |
516 |
customOptions.put(CompilerOptions.OPTION_NonNullAnnotationName, null); |
517 |
customOptions.put(CompilerOptions.OPTION_DefaultImportNullAnnotationTypes, CompilerOptions.ENABLED); |
518 |
runConformTest( |
519 |
new String[] { |
520 |
"libpack/Lib.java", |
521 |
"package libpack;\n" + |
522 |
"public class Lib {\n" + |
523 |
" public @NonNull Object getObject() { return new Object(); }\n" + |
524 |
"}\n", |
525 |
"X.java", |
526 |
"import libpack.Lib;\n" + |
527 |
"public class X {\n" + |
528 |
" @NonNull Object getObject(@NonNull Lib l) {\n" + |
529 |
" return l.getObject();\n" + |
530 |
" }\n" + |
531 |
"}\n" |
532 |
}, |
533 |
"", |
534 |
null/*classLibs*/, |
535 |
true/*shouldFlushOutputDirectory*/, |
536 |
null/*vmArguments*/, |
537 |
customOptions, |
538 |
null/*compilerRequestor*/); |
539 |
} |
540 |
// a non-null method returns a non-null return of another method, emulation names conflict with existing types |
541 |
public void test_nonnull_return_011() { |
542 |
Map customOptions = getCompilerOptions(); |
543 |
customOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR); |
544 |
customOptions.put(CompilerOptions.OPTION_NullableAnnotationName, "libpack.Lib"); |
545 |
customOptions.put(CompilerOptions.OPTION_NonNullAnnotationName, "libpack.Lib"); |
546 |
customOptions.put(CompilerOptions.OPTION_DefaultImportNullAnnotationTypes, CompilerOptions.ENABLED); |
547 |
runNegativeTest( |
548 |
true/*shouldFlushOutputDirectory*/, |
549 |
new String[] { |
550 |
"libpack/Lib.java", |
551 |
"package libpack;\n" + |
552 |
"public class Lib {\n" + |
553 |
"}\n", |
554 |
}, |
555 |
null/*classLibs*/, |
556 |
customOptions, |
557 |
"----------\n" + |
558 |
"1. ERROR in libpack\\Lib.java (at line 0)\n" + |
559 |
" package libpack;\n" + |
560 |
" ^\n" + |
561 |
"Buildpath problem: emulation of type libpack.Lib is requested (for null annotations) but a type of this name exists on the build path.\n" + |
562 |
"----------\n", |
563 |
JavacTestOptions.SKIP); |
564 |
} |
565 |
// a method tries to relax the null contract, super declares @NonNull return |
566 |
public void test_nonnull_return_012() { |
567 |
runConformTest( |
568 |
new String[] { |
569 |
"Lib.java", |
570 |
"public class Lib {\n" + |
571 |
" @NonNull Object getObject() { return new Object(); }\n" + |
572 |
"}\n" |
573 |
}); |
574 |
runNegativeTest( |
575 |
false /* flush output directory */, |
576 |
new String[] { |
577 |
"X.java", |
578 |
"public class X extends Lib {\n" + |
579 |
" @Override\n" + |
580 |
" @Nullable Object getObject() { return null; }\n" + |
581 |
"}\n" |
582 |
}, |
583 |
// compiler options |
584 |
null /* no class libraries */, |
585 |
null /* no custom options */, |
586 |
"----------\n" + |
587 |
"1. ERROR in X.java (at line 3)\n" + |
588 |
" @Nullable Object getObject() { return null; }\n" + |
589 |
" ^^^^^^^^^^^\n" + |
590 |
"Cannot relax null contract for method return, inherited method from Lib is declared as @NonNull.\n" + |
591 |
"----------\n", |
592 |
JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); |
593 |
} |
594 |
// a method body violates the inherited null contract, super declares @NonNull return |
595 |
public void test_nonnull_return_013() { |
596 |
runConformTest( |
597 |
new String[] { |
598 |
"Lib.java", |
599 |
"public class Lib {\n" + |
600 |
" @NonNull Object getObject() { return new Object(); }\n" + |
601 |
"}\n" |
602 |
}); |
603 |
runNegativeTest( |
604 |
false /* flush output directory */, |
605 |
new String[] { |
606 |
"X.java", |
607 |
"public class X extends Lib {\n" + |
608 |
" @Override\n" + |
609 |
" Object getObject() { return null; }\n" + |
610 |
"}\n" |
611 |
}, |
612 |
// compiler options |
613 |
null /* no class libraries */, |
614 |
null /* no custom options */, |
615 |
"----------\n" + |
616 |
"1. ERROR in X.java (at line 3)\n" + |
617 |
" Object getObject() { return null; }\n" + |
618 |
" ^^^^^^^^^^^^\n" + |
619 |
"Null contract violation: returning null from a method declared as @NonNull.\n" + |
620 |
"----------\n", |
621 |
JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); |
622 |
} |
623 |
|
624 |
} |