001package apps;
002
003/**
004 * Check how the Checker Framework and annotations interact.
005 * <p>
006 * Note: This deliberately causes SpotBugs (formally FindBugs) warnings! Do not
007 * remove or annotate them! Instead, when past its useful point, just comment
008 * out the body of the class so as to leave the code examples present.
009 * <p>
010 * Tests Nonnull, Nullable and CheckForNull from the javax.annotation package.
011 * <p>
012 * Comments indicate observed (and unobserved) warnings from the Checker
013 * Framework nullness processor
014 * <p>
015 * This has no main() because it's not expected to run: It will certainly throw
016 * a NullPointerException right away. The idea is for the CheckerFramework to
017 * find those in static analysis
018 * <p>
019 * Types are explicitly qualified (instead of using 'import') to make it
020 * completely clear which is being used at each point. That makes this the code
021 * less readable, so it's not recommended for general use.
022 * @see apps.FindBugsCheck
023 * @author Bob Jacobsen 2016
024 */
025public class CheckerFrameworkCheck {
026
027    void test() { // something that has to be executed on an object
028        System.out.println("test " + this.getClass());
029    }
030
031    /*  commenting out the rest of the file to avoid SpotBugs counting the deliberate warnings
032
033
034    public CheckerFrameworkCheck noAnnotationReturn() {
035        return null;                                // error: [return.type.incompatible] incompatible types in return. required: @Initialized @NonNull CheckerFrameworkCheck
036    }
037    public void noAnnotationParm(CheckerFrameworkCheck p) {
038        p.test();
039    }
040    public void noAnnotationTest() {
041        noAnnotationReturn().test();
042
043        noAnnotationParm(this);
044        noAnnotationParm(null);                     // error: [argument.type.incompatible] incompatible types in argument. required: @Initialized @NonNull CheckerFrameworkCheck
045
046        noAnnotationParm(noAnnotationReturn());
047        noAnnotationParm(jaNonnullReturn());
048        noAnnotationParm(jaNullableReturn());       // error: [argument.type.incompatible] incompatible types in argument. required: @Initialized @NonNull CheckerFrameworkCheck
049        noAnnotationParm(jaCheckForNullReturn());   // error: [argument.type.incompatible] incompatible types in argument. required: @Initialized @NonNull CheckerFrameworkCheck
050    }
051
052    // Test Nonnull
053
054    Nonnull public CheckerFrameworkCheck jaNonnullReturn() {
055        return null;                                // error: [return.type.incompatible] incompatible types in return. required: @Initialized @NonNull CheckerFrameworkCheck
056    }
057    public void jaNonNullParm(Nonnull CheckerFrameworkCheck p) {
058        p.test();
059    }
060    public void jaTestNonnull() {
061        jaNonnullReturn().test();
062
063        jaNonNullParm(this);
064        jaNonNullParm(null);                        // error: [argument.type.incompatible] incompatible types in argument. required: @Initialized @NonNull CheckerFrameworkCheck
065
066        jaNonNullParm(noAnnotationReturn());
067        jaNonNullParm(jaNonnullReturn());
068        jaNonNullParm(jaNullableReturn());          // error: [argument.type.incompatible] incompatible types in argument. required: @Initialized @NonNull CheckerFrameworkCheck
069        jaNonNullParm(jaCheckForNullReturn());      // error: [argument.type.incompatible] incompatible types in argument. required: @Initialized @NonNull CheckerFrameworkCheck
070    }
071
072    // Test Nullable
073
074    Nullable public CheckerFrameworkCheck jaNullableReturn() {
075        return null;
076    }
077    public void jaNullableParm(Nullable CheckerFrameworkCheck p) {
078        p.test();                                   // error: [dereference.of.nullable] dereference of possibly-null reference p
079    }
080    public void jaTestNullable() {
081        jaNullableReturn().test();                  // error: [dereference.of.nullable] dereference of possibly-null reference jaNullableReturn()
082
083        jaNullableParm(this);
084        jaNullableParm(null);
085
086        jaNullableParm(noAnnotationReturn());
087        jaNullableParm(jaNonnullReturn());
088        jaNullableParm(jaNullableReturn());
089        jaNullableParm(jaCheckForNullReturn());
090    }
091
092    // Test CheckForNull
093
094    CheckForNull public CheckerFrameworkCheck jaCheckForNullReturn() {
095        return null;
096    }
097    public void jaCheckForNullParm(CheckForNull CheckerFrameworkCheck p) {
098        p.test();                                   // error: [dereference.of.nullable] dereference of possibly-null reference p
099    }
100    public void jaTestCheckForNull() {
101        jaCheckForNullReturn().test();              // error: [dereference.of.nullable] dereference of possibly-null reference jaNullableReturn()
102
103        jaCheckForNullParm(this);
104        jaCheckForNullParm(null);
105
106        jaCheckForNullParm(noAnnotationReturn());
107        jaCheckForNullParm(jaNonnullReturn());
108        jaCheckForNullParm(jaNullableReturn());
109        jaCheckForNullParm(jaCheckForNullReturn());
110    }
111
112    end of commenting out file */
113}