From 2329ee5f848547bbf408cbf80853ffd8073b3860 Mon Sep 17 00:00:00 2001 From: Kevin Bourrillion Date: Mon, 12 Dec 2022 18:53:22 -0800 Subject: [PATCH] Add JSpecify 0.3 annotations, and a "fake" @NullnessUnspecified annotation --- .../org/jspecify/annotations/NonNull.java | 101 ++++++++++++ .../org/jspecify/annotations/NullMarked.java | 116 ++++++++++++++ .../jspecify/annotations/NullUnmarked.java | 87 +++++++++++ .../org/jspecify/annotations/Nullable.java | 144 ++++++++++++++++++ .../annotations/NullnessUnspecified.java | 39 +++++ .../java9-annotations/module-info.java | 3 +- .../org/jspecify/annotations/NonNull.java | 101 ++++++++++++ .../org/jspecify/annotations/NullMarked.java | 117 ++++++++++++++ .../jspecify/annotations/NullUnmarked.java | 87 +++++++++++ .../org/jspecify/annotations/Nullable.java | 144 ++++++++++++++++++ .../annotations/NullnessUnspecified.java | 39 +++++ 11 files changed, 977 insertions(+), 1 deletion(-) create mode 100644 third-party/java8-annotations/org/jspecify/annotations/NonNull.java create mode 100644 third-party/java8-annotations/org/jspecify/annotations/NullMarked.java create mode 100644 third-party/java8-annotations/org/jspecify/annotations/NullUnmarked.java create mode 100644 third-party/java8-annotations/org/jspecify/annotations/Nullable.java create mode 100644 third-party/java8-annotations/org/jspecify/annotations/NullnessUnspecified.java create mode 100644 third-party/java9-annotations/org/jspecify/annotations/NonNull.java create mode 100644 third-party/java9-annotations/org/jspecify/annotations/NullMarked.java create mode 100644 third-party/java9-annotations/org/jspecify/annotations/NullUnmarked.java create mode 100644 third-party/java9-annotations/org/jspecify/annotations/Nullable.java create mode 100644 third-party/java9-annotations/org/jspecify/annotations/NullnessUnspecified.java diff --git a/third-party/java8-annotations/org/jspecify/annotations/NonNull.java b/third-party/java8-annotations/org/jspecify/annotations/NonNull.java new file mode 100644 index 00000000000..771c769564c --- /dev/null +++ b/third-party/java8-annotations/org/jspecify/annotations/NonNull.java @@ -0,0 +1,101 @@ +/* + * Copyright 2022 The JSpecify Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jspecify.annotations; + +import static java.lang.annotation.ElementType.TYPE_USE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Indicates that the annotated type + * usage (commonly a parameter type or return type) is considered to exclude {@code null} + * as a value; rarely needed within {@linkplain NullMarked null-marked} code. + * + *

This annotation serves two primary purposes: + * + *

+ * + *

For a comprehensive introduction to JSpecify, please see jspecify.org. + * + *

Warning: These annotations are under development, and any aspect of their + * naming, locations, or design is subject to change until the JSpecify 1.0 release. Moreover, + * supporting analysis tools will be tracking the changes on varying schedules. Releasing a library + * using these annotations in its API is strongly discouraged at this time. + * + *

Non-null projection

+ * + *

In the following example, {@code MyOptional}'s type parameter {@code T} accepts only non-null + * type arguments, but {@code MyList}'s type parameter {@code E} will accept either a non-null or + * nullable type argument. + * + *

{@code
+ * // All the below is null-marked code
+ *
+ * class MyOptional { … }
+ *
+ * interface MyList {
+ *   // Returns the first non-null element, if such element exists.
+ *   MyOptional firstNonNull() { … } // problem here!
+ * }
+ *
+ * MyList<@Nullable String> maybeNulls = …
+ * MyList nonNulls = …
+ * }
+ * + *

Because {@code MyOptional} accepts only non-null type arguments, we need both {@code + * maybeNulls.firstNonNull()} and {@code nonNulls.firstNonNull()} to produce the same return type: + * {@code MyOptional!} (see notation). + * However, as specified above, they won't do that. In fact, there is a problem with the {@code + * firstNonNull} signature, since the type argument {@code String?} would not meet the requirements + * of {@code MyOptional}'s type parameter. + * + *

The solution is to project the type argument to its non-null counterpart: + * + *

{@code
+ * // Returns the first non-null element, if such element exists.
+ * MyOptional<@NonNull E> firstNonNull() { … } // problem fixed!
+ * }
+ * + *

Here, {@code @NonNull E} selects the non-null form of the type argument, whether it was + * already non-null or not, which is just what we need in this scenario. + * + *

If {@code E} has a non-null upper bound, then the apparent projection {@code @NonNull E} is + * redundant but harmless. + * + *

Nullable projection serves the equivalent purpose in + * the opposite direction, and is far more commonly useful. + * + *

If a type variable has all its usages being projected in one direction or the other, it + * should be given a non-null upper bound, and any non-null projections can then be removed. + * + *

Where it is not applicable

+ * + *

{@code @NonNull} is inapplicable in all the same + * locations as {@link Nullable}. + */ +@Documented +@Target(TYPE_USE) +@Retention(RUNTIME) +public @interface NonNull {} diff --git a/third-party/java8-annotations/org/jspecify/annotations/NullMarked.java b/third-party/java8-annotations/org/jspecify/annotations/NullMarked.java new file mode 100644 index 00000000000..bfc987c891d --- /dev/null +++ b/third-party/java8-annotations/org/jspecify/annotations/NullMarked.java @@ -0,0 +1,116 @@ +/* + * Copyright 2018-2020 The JSpecify Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jspecify.annotations; + +import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PACKAGE; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Indicates that the annotated element and the code transitively {@linkplain + * javax.lang.model.element.Element#getEnclosedElements() enclosed} within it are null-marked + * code: there, type usages are generally considered to exclude {@code null} as a value unless + * specified otherwise. Using this annotation avoids the need to write {@link NonNull @NonNull} many + * times throughout your code. + * + *

For a comprehensive introduction to JSpecify, please see jspecify.org. + * + *

Warning: These annotations are under development, and any aspect of their + * naming, locations, or design is subject to change until the JSpecify 1.0 release. Moreover, + * supporting analysis tools will be tracking the changes on varying schedules. Releasing a library + * using these annotations in its API is strongly discouraged at this time. + * + *

Effects of being null-marked

+ * + *

Within null-marked code, as a general rule, a type usage is considered non-null (to + * exclude {@code null} as a value) unless explicitly annotated as {@link Nullable}. However, there + * are several special cases to address. + * + *

Special cases

+ * + *

Within null-marked code: + * + *

+ * + *

Where it can be used

+ * + * {@code @NullMarked} and {@link NullUnmarked @NullUnmarked} can be used on any package, class, + * method, or constructor declaration; {@code @NullMarked} can be used on a module declaration as + * well. Special considerations: + * + * + */ +@Documented +@Target({PACKAGE, TYPE, METHOD, CONSTRUCTOR}) +@Retention(RUNTIME) +public @interface NullMarked {} diff --git a/third-party/java8-annotations/org/jspecify/annotations/NullUnmarked.java b/third-party/java8-annotations/org/jspecify/annotations/NullUnmarked.java new file mode 100644 index 00000000000..36d55de6509 --- /dev/null +++ b/third-party/java8-annotations/org/jspecify/annotations/NullUnmarked.java @@ -0,0 +1,87 @@ +/* + * Copyright 2022 The JSpecify Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jspecify.annotations; + +import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PACKAGE; +import static java.lang.annotation.ElementType.TYPE; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Indicates that the annotated element and the code transitively {@linkplain + * javax.lang.model.element.Element#getEnclosedElements() enclosed} within it is null-unmarked + * code: there, type usages generally have unspecified nullness unless explicitly + * annotated otherwise. + * + *

This annotation's purpose is to ease migration of a large existing codebase to null-marked + * status. It makes it possible to "flip the default" for new code added to a class or package even + * before that class or package has been fully migrated. Since new code is the most important code + * to analyze, this is strongly recommended as a temporary measure whenever necessary. However, once + * a codebase has been fully migrated it would be appropriate to ban use of this annotation. + * + *

For a comprehensive introduction to JSpecify, please see jspecify.org. + * + *

Warning: These annotations are under development, and any aspect of their + * naming, locations, or design is subject to change until the JSpecify 1.0 release. Moreover, + * supporting analysis tools will track with these changes on varying schedules. Releasing a library + * using these annotations in its API is strongly discouraged at this time. + * + *

Null-marked and null-unmarked code

+ * + *

{@link NullMarked} and this annotation work as a pair to include and exclude sections of code + * from null-marked status (respectively). Specifically, code is considered null-marked if the most + * narrowly enclosing element annotated with either of these two annotations exists and is annotated + * with {@code @NullMarked}. + * + *

Otherwise it is considered null-unmarked. This can happen in two ways: either it is more + * narrowly enclosed by a {@code @NullUnmarked}-annotated element than by any + * {@code @NullMarked}-annotated element, or neither annotation is present on any enclosing element. + * No distinction is made between these cases. + * + *

The effects of being null-marked are described in the Effects section of {@code NullMarked}. + * + *

Unspecified nullness

+ * + *

Within null-unmarked code, a type usage with no nullness annotation has unspecified + * nullness (Why?). This means that, while there is always + * some correct way to annotate it for nullness, that information is missing: we do not + * know whether it includes or excludes {@code null} as a value. In such a case, tools can vary + * widely in how strict or lenient their enforcement is, or might make it configurable. + * + *

For more, please see this more comprehensive + * discussion of unspecified nullness. + * + *

There is no way for an individual type usage within null-marked code to have unspecified + * nullness. (Why?) + * + *

Where it can be used

+ * + * The information in the Where it can be used section of {@code + * NullMarked} applies as well to this annotation. + */ +// TODO(kevinb9n): word the middle section better with good words +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({PACKAGE, TYPE, METHOD, CONSTRUCTOR}) +public @interface NullUnmarked {} diff --git a/third-party/java8-annotations/org/jspecify/annotations/Nullable.java b/third-party/java8-annotations/org/jspecify/annotations/Nullable.java new file mode 100644 index 00000000000..8d07ca3a244 --- /dev/null +++ b/third-party/java8-annotations/org/jspecify/annotations/Nullable.java @@ -0,0 +1,144 @@ +/* + * Copyright 2018-2020 The JSpecify Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jspecify.annotations; + +import static java.lang.annotation.ElementType.TYPE_USE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Indicates that the annotated type + * usage (commonly a parameter type or return type) is considered to include {@code null} as a + * value. + * + *

Example usages: + * + *

{@code
+ * @Nullable String field;
+ *
+ * @Nullable String getField() { return field; }
+ *
+ * void setField(@Nullable String value) { field = value; }
+ *
+ * List<@Nullable String> getList() { … }
+ * }
+ * + *

For a comprehensive introduction to JSpecify, please see jspecify.org. + * + *

Warning: These annotations are under development, and any aspect of their + * naming, locations, or design is subject to change until the JSpecify 1.0 release. Moreover, + * supporting analysis tools will be tracking the changes on varying schedules. Releasing a library + * using these annotations in its API is strongly discouraged at this time. + * + *

Meaning per each kind of type usage

+ * + *

The essential meaning of this annotation is always the same: the type it annotates is + * considered to include {@code null} as a value. But this may affect your code a little differently + * based on the kind of type usage involved. + * + *

+ * + *

Where it is applicable

+ * + *

This annotation and {@link NonNull} are applicable to any type usage except the + * following cases, where they have no defined meaning: + * + *

+ * + * Whether the code is {@link NullMarked} also has no consequence in the above locations. + * + *

Unannotated type usages

+ * + *

For a type usage where nullness annotations are applicable but + * not present, its nullness depends on whether it appears within {@linkplain NullMarked + * null-marked} code; see that class for details. Note in particular that nullness information from + * a superclass is never automatically "inherited". + */ +@Documented +@Target(TYPE_USE) +@Retention(RUNTIME) +public @interface Nullable {} diff --git a/third-party/java8-annotations/org/jspecify/annotations/NullnessUnspecified.java b/third-party/java8-annotations/org/jspecify/annotations/NullnessUnspecified.java new file mode 100644 index 00000000000..0542dc79c91 --- /dev/null +++ b/third-party/java8-annotations/org/jspecify/annotations/NullnessUnspecified.java @@ -0,0 +1,39 @@ +/* + * Copyright 2018-2020 The JSpecify Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jspecify.annotations; + +import static java.lang.annotation.ElementType.TYPE_USE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/* + + + This is a fake annotation that does not exist in the JSpecify + release, and with no expectation of being added! + + Once Kotlin supports @NullUnmarked, the tests can be updated + and this should be removed. + + + */ +@Documented +@Target(TYPE_USE) +@Retention(RUNTIME) +public @interface NullnessUnspecified {} diff --git a/third-party/java9-annotations/module-info.java b/third-party/java9-annotations/module-info.java index 77450ed8425..8e1110f355b 100644 --- a/third-party/java9-annotations/module-info.java +++ b/third-party/java9-annotations/module-info.java @@ -1,4 +1,5 @@ module java9_annotations { + exports org.jspecify.annotations; exports org.jspecify.nullness; // add packages needed to export -} \ No newline at end of file +} diff --git a/third-party/java9-annotations/org/jspecify/annotations/NonNull.java b/third-party/java9-annotations/org/jspecify/annotations/NonNull.java new file mode 100644 index 00000000000..771c769564c --- /dev/null +++ b/third-party/java9-annotations/org/jspecify/annotations/NonNull.java @@ -0,0 +1,101 @@ +/* + * Copyright 2022 The JSpecify Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jspecify.annotations; + +import static java.lang.annotation.ElementType.TYPE_USE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Indicates that the annotated type + * usage (commonly a parameter type or return type) is considered to exclude {@code null} + * as a value; rarely needed within {@linkplain NullMarked null-marked} code. + * + *

This annotation serves two primary purposes: + * + *

+ * + *

For a comprehensive introduction to JSpecify, please see jspecify.org. + * + *

Warning: These annotations are under development, and any aspect of their + * naming, locations, or design is subject to change until the JSpecify 1.0 release. Moreover, + * supporting analysis tools will be tracking the changes on varying schedules. Releasing a library + * using these annotations in its API is strongly discouraged at this time. + * + *

Non-null projection

+ * + *

In the following example, {@code MyOptional}'s type parameter {@code T} accepts only non-null + * type arguments, but {@code MyList}'s type parameter {@code E} will accept either a non-null or + * nullable type argument. + * + *

{@code
+ * // All the below is null-marked code
+ *
+ * class MyOptional { … }
+ *
+ * interface MyList {
+ *   // Returns the first non-null element, if such element exists.
+ *   MyOptional firstNonNull() { … } // problem here!
+ * }
+ *
+ * MyList<@Nullable String> maybeNulls = …
+ * MyList nonNulls = …
+ * }
+ * + *

Because {@code MyOptional} accepts only non-null type arguments, we need both {@code + * maybeNulls.firstNonNull()} and {@code nonNulls.firstNonNull()} to produce the same return type: + * {@code MyOptional!} (see notation). + * However, as specified above, they won't do that. In fact, there is a problem with the {@code + * firstNonNull} signature, since the type argument {@code String?} would not meet the requirements + * of {@code MyOptional}'s type parameter. + * + *

The solution is to project the type argument to its non-null counterpart: + * + *

{@code
+ * // Returns the first non-null element, if such element exists.
+ * MyOptional<@NonNull E> firstNonNull() { … } // problem fixed!
+ * }
+ * + *

Here, {@code @NonNull E} selects the non-null form of the type argument, whether it was + * already non-null or not, which is just what we need in this scenario. + * + *

If {@code E} has a non-null upper bound, then the apparent projection {@code @NonNull E} is + * redundant but harmless. + * + *

Nullable projection serves the equivalent purpose in + * the opposite direction, and is far more commonly useful. + * + *

If a type variable has all its usages being projected in one direction or the other, it + * should be given a non-null upper bound, and any non-null projections can then be removed. + * + *

Where it is not applicable

+ * + *

{@code @NonNull} is inapplicable in all the same + * locations as {@link Nullable}. + */ +@Documented +@Target(TYPE_USE) +@Retention(RUNTIME) +public @interface NonNull {} diff --git a/third-party/java9-annotations/org/jspecify/annotations/NullMarked.java b/third-party/java9-annotations/org/jspecify/annotations/NullMarked.java new file mode 100644 index 00000000000..a8752e68945 --- /dev/null +++ b/third-party/java9-annotations/org/jspecify/annotations/NullMarked.java @@ -0,0 +1,117 @@ +/* + * Copyright 2018-2020 The JSpecify Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jspecify.annotations; + +import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.MODULE; +import static java.lang.annotation.ElementType.PACKAGE; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Indicates that the annotated element and the code transitively {@linkplain + * javax.lang.model.element.Element#getEnclosedElements() enclosed} within it are null-marked + * code: there, type usages are generally considered to exclude {@code null} as a value unless + * specified otherwise. Using this annotation avoids the need to write {@link NonNull @NonNull} many + * times throughout your code. + * + *

For a comprehensive introduction to JSpecify, please see jspecify.org. + * + *

Warning: These annotations are under development, and any aspect of their + * naming, locations, or design is subject to change until the JSpecify 1.0 release. Moreover, + * supporting analysis tools will be tracking the changes on varying schedules. Releasing a library + * using these annotations in its API is strongly discouraged at this time. + * + *

Effects of being null-marked

+ * + *

Within null-marked code, as a general rule, a type usage is considered non-null (to + * exclude {@code null} as a value) unless explicitly annotated as {@link Nullable}. However, there + * are several special cases to address. + * + *

Special cases

+ * + *

Within null-marked code: + * + *

+ * + *

Where it can be used

+ * + * {@code @NullMarked} and {@link NullUnmarked @NullUnmarked} can be used on any package, class, + * method, or constructor declaration; {@code @NullMarked} can be used on a module declaration as + * well. Special considerations: + * + * + */ +@Documented +@Target({MODULE, PACKAGE, TYPE, METHOD, CONSTRUCTOR}) +@Retention(RUNTIME) +public @interface NullMarked {} diff --git a/third-party/java9-annotations/org/jspecify/annotations/NullUnmarked.java b/third-party/java9-annotations/org/jspecify/annotations/NullUnmarked.java new file mode 100644 index 00000000000..36d55de6509 --- /dev/null +++ b/third-party/java9-annotations/org/jspecify/annotations/NullUnmarked.java @@ -0,0 +1,87 @@ +/* + * Copyright 2022 The JSpecify Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jspecify.annotations; + +import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PACKAGE; +import static java.lang.annotation.ElementType.TYPE; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Indicates that the annotated element and the code transitively {@linkplain + * javax.lang.model.element.Element#getEnclosedElements() enclosed} within it is null-unmarked + * code: there, type usages generally have unspecified nullness unless explicitly + * annotated otherwise. + * + *

This annotation's purpose is to ease migration of a large existing codebase to null-marked + * status. It makes it possible to "flip the default" for new code added to a class or package even + * before that class or package has been fully migrated. Since new code is the most important code + * to analyze, this is strongly recommended as a temporary measure whenever necessary. However, once + * a codebase has been fully migrated it would be appropriate to ban use of this annotation. + * + *

For a comprehensive introduction to JSpecify, please see jspecify.org. + * + *

Warning: These annotations are under development, and any aspect of their + * naming, locations, or design is subject to change until the JSpecify 1.0 release. Moreover, + * supporting analysis tools will track with these changes on varying schedules. Releasing a library + * using these annotations in its API is strongly discouraged at this time. + * + *

Null-marked and null-unmarked code

+ * + *

{@link NullMarked} and this annotation work as a pair to include and exclude sections of code + * from null-marked status (respectively). Specifically, code is considered null-marked if the most + * narrowly enclosing element annotated with either of these two annotations exists and is annotated + * with {@code @NullMarked}. + * + *

Otherwise it is considered null-unmarked. This can happen in two ways: either it is more + * narrowly enclosed by a {@code @NullUnmarked}-annotated element than by any + * {@code @NullMarked}-annotated element, or neither annotation is present on any enclosing element. + * No distinction is made between these cases. + * + *

The effects of being null-marked are described in the Effects section of {@code NullMarked}. + * + *

Unspecified nullness

+ * + *

Within null-unmarked code, a type usage with no nullness annotation has unspecified + * nullness (Why?). This means that, while there is always + * some correct way to annotate it for nullness, that information is missing: we do not + * know whether it includes or excludes {@code null} as a value. In such a case, tools can vary + * widely in how strict or lenient their enforcement is, or might make it configurable. + * + *

For more, please see this more comprehensive + * discussion of unspecified nullness. + * + *

There is no way for an individual type usage within null-marked code to have unspecified + * nullness. (Why?) + * + *

Where it can be used

+ * + * The information in the Where it can be used section of {@code + * NullMarked} applies as well to this annotation. + */ +// TODO(kevinb9n): word the middle section better with good words +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({PACKAGE, TYPE, METHOD, CONSTRUCTOR}) +public @interface NullUnmarked {} diff --git a/third-party/java9-annotations/org/jspecify/annotations/Nullable.java b/third-party/java9-annotations/org/jspecify/annotations/Nullable.java new file mode 100644 index 00000000000..8d07ca3a244 --- /dev/null +++ b/third-party/java9-annotations/org/jspecify/annotations/Nullable.java @@ -0,0 +1,144 @@ +/* + * Copyright 2018-2020 The JSpecify Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jspecify.annotations; + +import static java.lang.annotation.ElementType.TYPE_USE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Indicates that the annotated type + * usage (commonly a parameter type or return type) is considered to include {@code null} as a + * value. + * + *

Example usages: + * + *

{@code
+ * @Nullable String field;
+ *
+ * @Nullable String getField() { return field; }
+ *
+ * void setField(@Nullable String value) { field = value; }
+ *
+ * List<@Nullable String> getList() { … }
+ * }
+ * + *

For a comprehensive introduction to JSpecify, please see jspecify.org. + * + *

Warning: These annotations are under development, and any aspect of their + * naming, locations, or design is subject to change until the JSpecify 1.0 release. Moreover, + * supporting analysis tools will be tracking the changes on varying schedules. Releasing a library + * using these annotations in its API is strongly discouraged at this time. + * + *

Meaning per each kind of type usage

+ * + *

The essential meaning of this annotation is always the same: the type it annotates is + * considered to include {@code null} as a value. But this may affect your code a little differently + * based on the kind of type usage involved. + * + *

+ * + *

Where it is applicable

+ * + *

This annotation and {@link NonNull} are applicable to any type usage except the + * following cases, where they have no defined meaning: + * + *

+ * + * Whether the code is {@link NullMarked} also has no consequence in the above locations. + * + *

Unannotated type usages

+ * + *

For a type usage where nullness annotations are applicable but + * not present, its nullness depends on whether it appears within {@linkplain NullMarked + * null-marked} code; see that class for details. Note in particular that nullness information from + * a superclass is never automatically "inherited". + */ +@Documented +@Target(TYPE_USE) +@Retention(RUNTIME) +public @interface Nullable {} diff --git a/third-party/java9-annotations/org/jspecify/annotations/NullnessUnspecified.java b/third-party/java9-annotations/org/jspecify/annotations/NullnessUnspecified.java new file mode 100644 index 00000000000..0542dc79c91 --- /dev/null +++ b/third-party/java9-annotations/org/jspecify/annotations/NullnessUnspecified.java @@ -0,0 +1,39 @@ +/* + * Copyright 2018-2020 The JSpecify Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jspecify.annotations; + +import static java.lang.annotation.ElementType.TYPE_USE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/* + + + This is a fake annotation that does not exist in the JSpecify + release, and with no expectation of being added! + + Once Kotlin supports @NullUnmarked, the tests can be updated + and this should be removed. + + + */ +@Documented +@Target(TYPE_USE) +@Retention(RUNTIME) +public @interface NullnessUnspecified {}