1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
|
// Test file for nullness parameter and return checks.
import org.checkerframework.checker.nullness.qual.*;
interface Noop {
void noop();
}
interface FunctionNull<T extends @Nullable Object, R> {
R apply(T t);
}
interface Supplier<R extends @Nullable Object> {
R supply();
}
interface BiFunctionNull<T, U, R> {
R apply(T t, U u);
}
class LambdaNullness {
// Annotations in lamba expressions, in static, instance of fields initializers are stored on
// the last declared constructor.
//
// For example, the annotation for @Nullable Integer x on f7's initializer
// is stored on here because it is the last defined constructor.
//
// See TypeFromElement::annotateParam
LambdaNullness(FunctionNull<String, String> f, Object e) {}
// No parameters; result is void
Noop f1 = () -> {};
// No parameters, expression body
Supplier<Integer> f2a = () -> 42;
// No parameters, expression body
// :: error: (return.type.incompatible)
Supplier<Integer> f2b = () -> null;
// No parameters, expression body
Supplier<@Nullable Void> f3 = () -> null;
// No parameters, block body with return
Supplier<Integer> f4a =
() -> {
return 42;
};
// No parameters, block body with return
Supplier<@Nullable Integer> f4b =
() -> {
// :: error: (assignment.type.incompatible)
@NonNull String s = null;
return null;
};
// No parameters, void block body
Noop f5 =
() -> {
System.gc();
};
// Complex block body with returns
Supplier<Integer> f6 =
() -> {
if (true) {
return 12;
} else {
int result = 15;
for (int i = 1; i < 10; i++) {
result *= i;
}
// :: error: (return.type.incompatible)
return null;
}
};
// Single declared-type parameter
FunctionNull<@Nullable Integer, Integer> f7 = (@Nullable Integer x) -> 1;
// Single declared-type parameter
FunctionNull<@Nullable String, String> f9 =
// :: error: (lambda.param.type.incompatible)
(@NonNull String x) -> {
return x + "";
};
// Single inferred-type parameter
FunctionNull<@NonNull Integer, Integer> f10 = (x) -> x + 1;
// Parentheses optional for single
FunctionNull<@Nullable Integer, Integer> f11 = x -> 1;
// Multiple declared-type parameters
BiFunctionNull<Integer, Integer, Integer> f16 =
(@Nullable Integer x, final Integer y) -> {
x = null;
// :: error: (unboxing.of.nullable)
return x + y;
};
// Multiple inferred-type parameters
BiFunctionNull<String, String, String> f18 = (x, y) -> x + y;
// Infer based on context.
FunctionNull<@Nullable String, String> fn =
(s) -> {
// :: error: (dereference.of.nullable)
s.toString();
return "";
};
}
|