Last active
April 1, 2017 19:26
-
-
Save bitterfox/615cc982b6d846aa763d3ea313b31350 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.*; | |
import java.util.stream.*; | |
import org.checkerframework.checker.nullness.qual.*; | |
/** | |
* export CHECKERFRAMEWORK=${HOME}/lib/checker-framework-2.1.9 | |
* alias javach='$CHECKERFRAMEWORK/checker/bin/javac' | |
* export PATH=~/bin/jdk1.8.0_51/bin:$PATH | |
* javach -processor org.checkerframework.checker.nullness.NullnessChecker Main.java -J-Duser.language=en | |
*/ | |
public class Main { | |
Object[] omitNullsOriginal(Object[] args) { | |
int size = 0; | |
for (Object s : args) { | |
if (s != null) { | |
size++; | |
} | |
} | |
Object[] ret = new Object[size]; | |
for (int i = 0, j = 0; i < args.length; i++) { | |
if (args[i] != null) { | |
ret[j++] = args[i]; | |
} | |
} | |
return ret; | |
} | |
@NonNull Object @NonNull [] omitNulls1(@Nullable Object @NonNull [] args) { | |
int size = 0; | |
for (@Nullable Object s : args) { | |
if (s != null) { | |
size++; | |
} | |
} | |
@NonNull Object @NonNull [] ret = new Object[size]; | |
for (int i = 0, j = 0; i < args.length; i++) { | |
if (args[i] != null) { | |
ret[j++] = args[i]; | |
} | |
} | |
return ret; | |
} | |
// trying to use PolyNull | |
@NonNull Object @PolyNull [] omitNulls2(@Nullable Object @PolyNull [] args) { | |
if (args == null) { | |
return null; | |
} | |
int size = 0; | |
for (@Nullable Object s : args) { | |
if (s != null) { | |
size++; | |
} | |
} | |
@NonNull Object @NonNull [] ret = new Object[size]; | |
for (int i = 0, j = 0; i < args.length; i++) { | |
if (args[i] != null) { | |
ret[j++] = args[i]; | |
} | |
} | |
return ret; | |
} | |
// trying to use generics and type inference | |
<T> @NonNull T @PolyNull [] omitNulls3(@Nullable T @PolyNull [] args) { | |
if (args == null) { | |
return null; | |
} | |
int size = 0; | |
for (@Nullable Object s : args) { | |
if (s != null) { | |
size++; | |
} | |
} | |
@NonNull T @NonNull [] ret = newArray(size); | |
for (int i = 0, j = 0; i < args.length; i++) { | |
if (args[i] != null) { | |
ret[j++] = args[i]; | |
} | |
} | |
return ret; | |
} | |
@SuppressWarnings("unchecked") | |
<T> T[] newArray(int size) { | |
return (T[])new Object[size]; | |
} | |
// trying to use Stream API | |
<T> @NonNull T @PolyNull [] omitNulls4(@Nullable T @PolyNull [] args) { | |
if (args == null) { | |
return null; | |
} | |
/* | |
return Arrays.stream(args) | |
.filter(o -> o != null) | |
.toArray(this::newArray); // error: | |
Main.java:105: warning: [methodref.inference.unimplemented] This version of the Checker Framework does not type-check method references with implicit type arguments. | |
.toArray(this::newArray); // error | |
^ | |
Main.java:105: error: [return.type.incompatible] incompatible types in return. | |
.toArray(this::newArray); // error | |
^ | |
found : T extends @Initialized @Nullable Object @Initialized @NonNull [] | |
required: T extends @Initialized @NonNull Object @Initialized @PolyNull [] | |
1 error | |
1 warning | |
*/ | |
/* return Arrays.stream(args) | |
.filter(o -> o != null) | |
.<@NonNull T>map(o -> (@NonNull T)o) | |
.toArray(this::newArray); // still error: | |
Main.java:112: warning: [methodref.inference.unimplemented] This version of the Checker Framework does not type-check method references with implicit type arguments. | |
.toArray(this::newArray); | |
^ | |
Main.java:112: error: [return.type.incompatible] incompatible types in return. | |
.toArray(this::newArray); | |
^ | |
found : T extends @Initialized @Nullable Object @Initialized @NonNull [] | |
required: T extends @Initialized @NonNull Object @Initialized @PolyNull [] | |
Main.java:111: warning: [cast.unsafe] "T extends @Initialized @Nullable Object" may not be casted to the type "T extends @Initialized @NonNull Object" | |
.<@NonNull T>map(o -> (@NonNull T)o) | |
^ | |
1 error | |
2 warnings | |
*/ | |
/* return Arrays.stream(args) | |
.filter(o -> o != null) | |
.<@NonNull T>map(o -> (@NonNull T)o) | |
.collect(Collectors.toList()).toArray(newArray(0)); // error | |
Main.java:142: error: [return.type.incompatible] incompatible types in return. | |
.collect(Collectors.toList()).toArray(newArray(0)); | |
^ | |
found : ?[ extends @UnknownKeyFor Object super @KeyForBottom Void] @UnknownKeyFor [] | |
required: T[ extends @UnknownKeyFor Object super @KeyForBottom Void] @UnknownKeyFor [] | |
Main.java:142: error: [return.type.incompatible] incompatible types in return. | |
.collect(Collectors.toList()).toArray(newArray(0)); | |
^ | |
found : @Initialized @Nullable ?[ extends @Initialized @Nullable Object super @Initialized @Nullable Void] @Initialized @NonNull [] | |
required: T[ extends @Initialized @NonNull Object super @Initialized @NonNull Void] @Initialized @PolyNull [] | |
Main.java:141: warning: [cast.unsafe] "T extends @Initialized @Nullable Object" may not be casted to the type "T extends @Initialized @NonNull Object" | |
.<@NonNull T>map(o -> (@NonNull T)o) | |
^ | |
2 errors | |
1 warning | |
*/ | |
/* | |
@NonNull T @NonNull [] ret = newArray(0); | |
return Arrays.stream(args) | |
.filter(o -> o != null) | |
.<@NonNull T>map(o -> (@NonNull T)o) | |
.collect(Collectors.toList()).toArray(ret); // error | |
Main.java:166: error: [return.type.incompatible] incompatible types in return. | |
.collect(Collectors.toList()).toArray(ret); | |
^ | |
found : T[ extends @Initialized @Nullable Object super @Initialized @Nullable Void] @Initialized @NonNull [] | |
required: T[ extends @Initialized @NonNull Object super @Initialized @NonNull Void] @Initialized @PolyNull [] | |
Main.java:165: warning: [cast.unsafe] "T extends @Initialized @Nullable Object" may not be casted to the type "T extends @Initialized @NonNull Object" | |
.<@NonNull T>map(o -> (@NonNull T)o) | |
^ | |
1 error | |
1 warning | |
*/ | |
return newArray(0); // I've give up \(;_;)/ | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment