diff --git a/gradle.properties b/gradle.properties index 309be6e..34b01b8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,7 +14,7 @@ # limitations under the License. # -projectVersion=26.0.2 +projectVersion=27.0.0 kotlin.code.style=official kotlin.mpp.stability.nowarn=true kotlin.stdlib.default.dependency=false diff --git a/src/jvmMain/java/org/jetbrains/annotations/NotOwning.java b/src/jvmMain/java/org/jetbrains/annotations/NotOwning.java new file mode 100644 index 0000000..5af635d --- /dev/null +++ b/src/jvmMain/java/org/jetbrains/annotations/NotOwning.java @@ -0,0 +1,47 @@ +package org.jetbrains.annotations; + +import java.io.Closeable; +import java.io.InputStream; +import java.io.StringWriter; +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.util.Properties; + +/** + * Indicates that responsibility for closing a {@link Closeable} resource is not transferred. + * + *

+ * When marked on a method, the return value of the method is still owned and managed by the callee and therefore the + * caller must not close it. For example, a class may encapsulate an {@code OutputStream}, and expose it via a + * getter. The getter does not transfer responsibility for closing the stream. + * + *

+ * When marked on a parameter, the callee does not take responsibility for closing the {@code Closeable}, and + * responsibility for closing it stays with the caller. For example, {@link Properties#load(InputStream)} doesn't close + * its parameter, and relying on that method to close the {@code InputStream} would be a mistake. + * + *

+ * When marked on a class or interface implementing {@code Closeable}, indicates that this class and its subclasses do + * not contain resources which must be closed, and therefore not closing them won't lead to any resource leak. + * For example, {@link StringWriter} does not hold any external resources despite implementing {@code Closeable}, and + * closing it has no effect. Note that this does not mean that the class cannot be closed, only that + * it does not have to be closed. + * + *

+ * This annotation also could be used as a meta-annotation, to define other annotations for convenience. + * + *

+ * This annotation may be used by tools to check when a closeable resource hasn't been closed or closed by the wrong + * party. Note that this annotation has no effect when used for types that don't implement {@link Closeable}. + * + * @see Owning + */ +@Documented +@Retention(RetentionPolicy.CLASS) +@Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE}) +@ApiStatus.Experimental +public @interface NotOwning { +} diff --git a/src/jvmMain/java/org/jetbrains/annotations/Owning.java b/src/jvmMain/java/org/jetbrains/annotations/Owning.java new file mode 100644 index 0000000..8f8ad68 --- /dev/null +++ b/src/jvmMain/java/org/jetbrains/annotations/Owning.java @@ -0,0 +1,57 @@ +package org.jetbrains.annotations; + +import java.io.BufferedWriter; +import java.io.Closeable; +import java.io.Writer; +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.nio.file.Files; + +/** + * Indicates a transfer of responsibility for closing a {@link Closeable} resource. + * + *

+ * When marked on a method, the responsibility for closing the return value of this method is transferred to the caller. + * For example, the {@link Files#newInputStream} method constructs an {@code InputStream} and returns it, then the + * caller is responsible for closing this {@code InputStream}. + * + *

+ * When marked on a parameter, the responsibility for closing is transferred from the caller to the callee. For example, + * the following method's parameter may be annotated with {@code @Owning}: + *

+ * {@code
+ * public static void closeQuietly(@Owning Closeable resource) {
+ *     try {
+ *         resource.close();
+ *     } catch (IOException ignored) {
+ *     }
+ * }
+ * }
+ * 
+ * Another example is {@link BufferedWriter#BufferedWriter(Writer)} which wraps a {@code Writer}, as the responsibility + * for closing the wrapped writer is transferred away from the caller (to the {@code BufferedWriter}). + * + *

+ * When marked on a class or interface implementing {@code Closeable}, indicates that this class and its subclasses + * contain resources which must be closed, and therefore {@link Closeable#close close()} must be called at some + * point. This is the default assumption for most closeable classes; this annotation may be used to override a + * {@link NotOwning} annotation in a superclass. + * + *

+ * This annotation also could be used as a meta-annotation, to define other annotations for convenience. + * + *

+ * This annotation may be used by tools to check when a closeable resource hasn't been closed or closed by the wrong + * party. Note that this annotation has no effect when used for types that don't implement {@link Closeable}. + * + * @see NotOwning + */ +@Documented +@Retention(RetentionPolicy.CLASS) +@Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE}) +@ApiStatus.Experimental +public @interface Owning { +}