1 /* 2 * Copyright 2020 The JSpecify Authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 import org.jspecify.annotations.NullMarked; 17 import org.jspecify.annotations.Nullable; 18 import org.jspecify.annotations.NullnessUnspecified; 19 20 /* 21 * Warning: I have probably gotten some things wrong in adding jspecify_* comments in this file. 22 * (Now, that may be the case for *any* file :) But it is particularly likely in this one.) 23 * Additionally, some checks would probably have different results under slightly different 24 * implementations of type inference and/or if we passed explicit type arguments. Fortunately, most 25 * of the checks here are for edge cases that are unlikely to arise in practice. 26 */ 27 @NullMarked 28 class ComplexParametric { 29 interface SuperSuper<T extends @Nullable Object> { t()30 Lib<T> t(); 31 tUnspec()32 Lib<@NullnessUnspecified T> tUnspec(); 33 tUnionNull()34 Lib<@Nullable T> tUnionNull(); 35 checkT(Lib<T> lib)36 void checkT(Lib<T> lib); 37 checkTUnspec(Lib<@NullnessUnspecified T> lib)38 void checkTUnspec(Lib<@NullnessUnspecified T> lib); 39 checkTUnionNull(Lib<@Nullable T> lib)40 void checkTUnionNull(Lib<@Nullable T> lib); 41 42 // And some method that do not use T: 43 checkNeverNull(Lib<? extends Object> lib)44 void checkNeverNull(Lib<? extends Object> lib); 45 checkUnspecNull(Lib<@NullnessUnspecified U> lib)46 <U> void checkUnspecNull(Lib<@NullnessUnspecified U> lib); 47 } 48 49 interface SuperNeverNever<T extends Object & Foo> extends SuperSuper<T> { x()50 default void x() { 51 checkNeverNull(t()); 52 // jspecify_nullness_not_enough_information 53 checkUnspecNull(t()); 54 checkT(t()); 55 // jspecify_nullness_not_enough_information 56 checkTUnspec(t()); 57 // jspecify_nullness_mismatch 58 checkTUnionNull(t()); 59 60 // jspecify_nullness_not_enough_information 61 checkNeverNull(tUnspec()); 62 // jspecify_nullness_not_enough_information 63 checkUnspecNull(tUnspec()); 64 // jspecify_nullness_not_enough_information 65 checkT(tUnspec()); 66 // jspecify_nullness_not_enough_information 67 checkTUnspec(tUnspec()); 68 // jspecify_nullness_not_enough_information 69 checkTUnionNull(tUnspec()); 70 71 // jspecify_nullness_mismatch 72 checkNeverNull(tUnionNull()); 73 // jspecify_nullness_not_enough_information 74 this.<T>checkUnspecNull(tUnionNull()); 75 // jspecify_nullness_mismatch 76 checkT(tUnionNull()); 77 // jspecify_nullness_not_enough_information 78 checkTUnspec(tUnionNull()); 79 checkTUnionNull(tUnionNull()); 80 } 81 } 82 83 interface SuperNeverUnspec<T extends Object & @NullnessUnspecified Foo> extends SuperSuper<T> { x()84 default void x() { 85 checkNeverNull(t()); 86 // jspecify_nullness_not_enough_information 87 checkUnspecNull(t()); 88 checkT(t()); 89 // jspecify_nullness_not_enough_information 90 checkTUnspec(t()); 91 // jspecify_nullness_mismatch 92 checkTUnionNull(t()); 93 94 // jspecify_nullness_not_enough_information 95 checkNeverNull(tUnspec()); 96 // jspecify_nullness_not_enough_information 97 checkUnspecNull(tUnspec()); 98 // jspecify_nullness_not_enough_information 99 checkT(tUnspec()); 100 // jspecify_nullness_not_enough_information 101 checkTUnspec(tUnspec()); 102 // jspecify_nullness_not_enough_information 103 checkTUnionNull(tUnspec()); 104 105 // jspecify_nullness_mismatch 106 checkNeverNull(tUnionNull()); 107 // jspecify_nullness_not_enough_information 108 this.<T>checkUnspecNull(tUnionNull()); 109 // jspecify_nullness_mismatch 110 checkT(tUnionNull()); 111 // jspecify_nullness_not_enough_information 112 checkTUnspec(tUnionNull()); 113 checkTUnionNull(tUnionNull()); 114 } 115 } 116 117 interface SuperNeverUnionNull<T extends Object & @Nullable Foo> extends SuperSuper<T> { x()118 default void x() { 119 checkNeverNull(t()); 120 // jspecify_nullness_not_enough_information 121 checkUnspecNull(t()); 122 checkT(t()); 123 // jspecify_nullness_not_enough_information 124 checkTUnspec(t()); 125 // jspecify_nullness_mismatch 126 checkTUnionNull(t()); 127 128 // jspecify_nullness_not_enough_information 129 checkNeverNull(tUnspec()); 130 // jspecify_nullness_not_enough_information 131 checkUnspecNull(tUnspec()); 132 // jspecify_nullness_not_enough_information 133 checkT(tUnspec()); 134 // jspecify_nullness_not_enough_information 135 checkTUnspec(tUnspec()); 136 // jspecify_nullness_not_enough_information 137 checkTUnionNull(tUnspec()); 138 139 // jspecify_nullness_mismatch 140 checkNeverNull(tUnionNull()); 141 // jspecify_nullness_not_enough_information 142 this.<T>checkUnspecNull(tUnionNull()); 143 // jspecify_nullness_mismatch 144 checkT(tUnionNull()); 145 // jspecify_nullness_not_enough_information 146 checkTUnspec(tUnionNull()); 147 checkTUnionNull(tUnionNull()); 148 } 149 } 150 151 interface SuperUnspecNever<T extends @NullnessUnspecified Object & Foo> extends SuperSuper<T> { x()152 default void x() { 153 checkNeverNull(t()); 154 // jspecify_nullness_not_enough_information 155 checkUnspecNull(t()); 156 checkT(t()); 157 // jspecify_nullness_not_enough_information 158 checkTUnspec(t()); 159 // jspecify_nullness_mismatch 160 checkTUnionNull(t()); 161 162 // jspecify_nullness_not_enough_information 163 checkNeverNull(tUnspec()); 164 // jspecify_nullness_not_enough_information 165 checkUnspecNull(tUnspec()); 166 // jspecify_nullness_not_enough_information 167 checkT(tUnspec()); 168 // jspecify_nullness_not_enough_information 169 checkTUnspec(tUnspec()); 170 // jspecify_nullness_not_enough_information 171 checkTUnionNull(tUnspec()); 172 173 // jspecify_nullness_mismatch 174 checkNeverNull(tUnionNull()); 175 // jspecify_nullness_not_enough_information 176 this.<T>checkUnspecNull(tUnionNull()); 177 // jspecify_nullness_mismatch 178 checkT(tUnionNull()); 179 // jspecify_nullness_not_enough_information 180 checkTUnspec(tUnionNull()); 181 checkTUnionNull(tUnionNull()); 182 } 183 } 184 185 interface SuperUnspecUnspec<T extends @NullnessUnspecified Object & @NullnessUnspecified Foo> 186 extends SuperSuper<T> { 187 // TODO(cpovirk): Add method calls like in the other classes. 188 } 189 190 interface SuperUnspecUnionNull<T extends @NullnessUnspecified Object & @Nullable Foo> 191 extends SuperSuper<T> { 192 // TODO(cpovirk): Add method calls like in the other classes. 193 } 194 195 interface SuperUnionNullNever<T extends @Nullable Object & Foo> extends SuperSuper<T> { x()196 default void x() { 197 checkNeverNull(t()); 198 // jspecify_nullness_not_enough_information 199 checkUnspecNull(t()); 200 checkT(t()); 201 // jspecify_nullness_not_enough_information 202 checkTUnspec(t()); 203 // jspecify_nullness_mismatch 204 checkTUnionNull(t()); 205 206 // jspecify_nullness_not_enough_information 207 checkNeverNull(tUnspec()); 208 // jspecify_nullness_not_enough_information 209 checkUnspecNull(tUnspec()); 210 // jspecify_nullness_not_enough_information 211 checkT(tUnspec()); 212 // jspecify_nullness_not_enough_information 213 checkTUnspec(tUnspec()); 214 // jspecify_nullness_not_enough_information 215 checkTUnionNull(tUnspec()); 216 217 // jspecify_nullness_mismatch 218 checkNeverNull(tUnionNull()); 219 // jspecify_nullness_not_enough_information 220 this.<T>checkUnspecNull(tUnionNull()); 221 // jspecify_nullness_mismatch 222 checkT(tUnionNull()); 223 // jspecify_nullness_not_enough_information 224 checkTUnspec(tUnionNull()); 225 checkTUnionNull(tUnionNull()); 226 } 227 } 228 229 interface SuperUnionNullUnspec<T extends @Nullable Object & @NullnessUnspecified Foo> 230 extends SuperSuper<T> { 231 // TODO(cpovirk): Add method calls like in the other classes. 232 } 233 234 interface SuperUnionNullUnionNull<T extends @Nullable Object & @Nullable Foo> 235 extends SuperSuper<T> { x()236 default void x() { 237 // jspecify_nullness_mismatch 238 checkNeverNull(t()); 239 // jspecify_nullness_mismatch 240 checkUnspecNull(t()); 241 checkT(t()); 242 // jspecify_nullness_not_enough_information 243 checkTUnspec(t()); 244 // jspecify_nullness_mismatch 245 checkTUnionNull(t()); 246 247 // jspecify_nullness_mismatch 248 checkNeverNull(tUnspec()); 249 // jspecify_nullness_not_enough_information 250 checkUnspecNull(tUnspec()); 251 // jspecify_nullness_not_enough_information 252 checkT(tUnspec()); 253 // jspecify_nullness_not_enough_information 254 checkTUnspec(tUnspec()); 255 // jspecify_nullness_not_enough_information 256 checkTUnionNull(tUnspec()); 257 258 // jspecify_nullness_mismatch 259 checkNeverNull(tUnionNull()); 260 // jspecify_nullness_not_enough_information 261 this.<T>checkUnspecNull(tUnionNull()); 262 // jspecify_nullness_mismatch 263 checkT(tUnionNull()); 264 // jspecify_nullness_not_enough_information 265 checkTUnspec(tUnionNull()); 266 checkTUnionNull(tUnionNull()); 267 } 268 } 269 270 interface Foo {} 271 272 interface Lib<T extends @Nullable Object> {} 273 } 274