Introduce dedicated experimental annotation for Path extensions

#KT-19192
This commit is contained in:
Ilya Gorbunov
2020-10-15 02:23:02 +03:00
parent 997cd35e06
commit 9f659d74df
5 changed files with 77 additions and 37 deletions
+2
View File
@@ -77,6 +77,7 @@ compileKotlin {
"-Xmultifile-parts-inherit",
"-Xnormalize-constructor-calls=enable",
"-module-name", project.name,
"-Xopt-in=kotlin.RequiresOptIn",
"-Xopt-in=kotlin.contracts.ExperimentalContracts",
]
}
@@ -88,6 +89,7 @@ compileTestKotlin {
"-Xopt-in=kotlin.RequiresOptIn",
"-Xopt-in=kotlin.ExperimentalUnsignedTypes",
"-Xopt-in=kotlin.ExperimentalStdlibApi",
"-Xopt-in=kotlin.io.path.ExperimentalPathApi",
]
}
@@ -0,0 +1,37 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package kotlin.io.path
import kotlin.annotation.AnnotationTarget.*
/**
* This annotation marks the extensions and top-level functions for working with [java.nio.file.Path] considered experimental.
*
* > Beware using the annotated API especially if you're developing a library, since your library might become binary incompatible
* with the future versions of the standard library.
*
* Any usage of a declaration annotated with `@ExperimentalPathAPI` must be accepted either by
* annotating that usage with the [OptIn] annotation, e.g. `@OptIn(ExperimentalPathAPI::class)`,
* or by using the compiler argument `-Xopt-in=kotlin.io.path.ExperimentalPathAPI`.
*/
@RequiresOptIn(level = RequiresOptIn.Level.ERROR)
@Retention(AnnotationRetention.BINARY)
@Target(
CLASS,
ANNOTATION_CLASS,
PROPERTY,
FIELD,
LOCAL_VARIABLE,
VALUE_PARAMETER,
CONSTRUCTOR,
FUNCTION,
PROPERTY_GETTER,
PROPERTY_SETTER,
TYPEALIAS
)
@MustBeDocumented
@SinceKotlin("1.3")
public annotation class ExperimentalPathApi
@@ -20,7 +20,7 @@ import java.nio.file.StandardOpenOption
* Returns a new [InputStreamReader] for reading the content of this file.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
@kotlin.internal.InlineOnly
public inline fun Path.reader(charset: Charset = Charsets.UTF_8, vararg options: OpenOption): InputStreamReader {
return inputStream(*options).reader(charset)
@@ -34,7 +34,7 @@ public inline fun Path.reader(charset: Charset = Charsets.UTF_8, vararg options:
* @param options options to determine how the file is opened
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
@kotlin.internal.InlineOnly
public inline fun Path.bufferedReader(
charset: Charset = Charsets.UTF_8,
@@ -48,7 +48,7 @@ public inline fun Path.bufferedReader(
* Returns a new [OutputStreamWriter] for writing the content of this file.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
@kotlin.internal.InlineOnly
public inline fun Path.writer(charset: Charset = Charsets.UTF_8, vararg options: OpenOption): OutputStreamWriter {
return outputStream(*options).writer(charset)
@@ -62,7 +62,7 @@ public inline fun Path.writer(charset: Charset = Charsets.UTF_8, vararg options:
* @param options options to determine how the file is opened.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
@kotlin.internal.InlineOnly
public inline fun Path.bufferedWriter(
charset: Charset = Charsets.UTF_8,
@@ -76,7 +76,7 @@ public inline fun Path.bufferedWriter(
* Returns a new [PrintWriter] for writing the content of this file.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
@kotlin.internal.InlineOnly
public inline fun Path.printWriter(charset: Charset = Charsets.UTF_8, vararg options: OpenOption): PrintWriter {
return PrintWriter(bufferedWriter(charset, options = options))
@@ -90,7 +90,7 @@ public inline fun Path.printWriter(charset: Charset = Charsets.UTF_8, vararg opt
* @return the entire content of this file as a byte array.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
@kotlin.internal.InlineOnly
public inline fun Path.readBytes(): ByteArray {
return Files.readAllBytes(this)
@@ -106,7 +106,7 @@ public inline fun Path.readBytes(): ByteArray {
* @param options options to determine how the file is opened.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
@kotlin.internal.InlineOnly
public inline fun Path.writeBytes(array: ByteArray, vararg options: OpenOption): Unit {
Files.write(this, array, *options)
@@ -118,7 +118,7 @@ public inline fun Path.writeBytes(array: ByteArray, vararg options: OpenOption):
* @param array byte array to append to this file.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
@kotlin.internal.InlineOnly
public inline fun Path.appendBytes(array: ByteArray): Unit {
writeBytes(array, StandardOpenOption.APPEND)
@@ -133,7 +133,7 @@ public inline fun Path.appendBytes(array: ByteArray): Unit {
* @return the entire content of this file as a String.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
public fun Path.readText(charset: Charset = Charsets.UTF_8): String = readBytes().toString(charset)
/**
@@ -146,7 +146,7 @@ public fun Path.readText(charset: Charset = Charsets.UTF_8): String = readBytes(
* @param charset character set to use.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
public fun Path.writeText(text: String, charset: Charset = Charsets.UTF_8, vararg options: OpenOption): Unit {
writeBytes(text.toByteArray(charset), *options)
}
@@ -158,7 +158,7 @@ public fun Path.writeText(text: String, charset: Charset = Charsets.UTF_8, varar
* @param charset character set to use.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
public fun Path.appendText(text: String, charset: Charset = Charsets.UTF_8): Unit {
writeText(text, charset, StandardOpenOption.APPEND)
}
@@ -174,7 +174,7 @@ public fun Path.appendText(text: String, charset: Charset = Charsets.UTF_8): Uni
* @param action function to process file lines.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
public fun Path.forEachLine(charset: Charset = Charsets.UTF_8, vararg options: OpenOption, action: (line: String) -> Unit): Unit {
// Note: close is called at forEachLine
bufferedReader(charset, options = options).forEachLine(action)
@@ -187,7 +187,7 @@ public fun Path.forEachLine(charset: Charset = Charsets.UTF_8, vararg options: O
* equivalent to opening the file with the [READ][StandardOpenOption.READ] option.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
@kotlin.internal.InlineOnly
public inline fun Path.inputStream(vararg options: OpenOption): InputStream {
return Files.newInputStream(this, *options)
@@ -202,7 +202,7 @@ public inline fun Path.inputStream(vararg options: OpenOption): InputStream {
* options.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
@kotlin.internal.InlineOnly
public inline fun Path.outputStream(vararg options: OpenOption): OutputStream {
return Files.newOutputStream(this, *options)
@@ -217,7 +217,7 @@ public inline fun Path.outputStream(vararg options: OpenOption): OutputStream {
* @return list of file lines.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
@kotlin.internal.InlineOnly
public inline fun Path.readLines(charset: Charset = Charsets.UTF_8): List<String> {
return Files.readAllLines(this, charset)
@@ -231,7 +231,7 @@ public inline fun Path.readLines(charset: Charset = Charsets.UTF_8): List<String
* @return the value returned by [block].
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
@kotlin.internal.InlineOnly
public inline fun <T> Path.useLines(charset: Charset = Charsets.UTF_8, block: (Sequence<String>) -> T): T {
return bufferedReader(charset).use { block(it.lineSequence()) }
@@ -18,7 +18,7 @@ import java.nio.file.NoSuchFileException
* Returns the extension of this path (not including the dot), or an empty string if it doesn't have one.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
public val Path.extension: String
get() = fileName?.toString()?.substringAfterLast('.', "") ?: ""
@@ -27,7 +27,7 @@ public val Path.extension: String
* separate the names in the name sequence.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
public val Path.invariantSeparatorsPath: String
get() {
val separator = fileSystem.separator
@@ -39,7 +39,7 @@ public val Path.invariantSeparatorsPath: String
* this path has zero elements.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
public val Path.nameWithoutExtension: String
get() = fileName?.toString()?.substringBeforeLast(".") ?: ""
@@ -53,7 +53,7 @@ public val Path.nameWithoutExtension: String
* @throws IllegalArgumentException if this and base paths have different roots.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
public fun Path.relativeTo(base: Path): Path = try {
PathRelativizer.tryRelativeTo(this, base)
} catch (e: IllegalArgumentException) {
@@ -68,7 +68,7 @@ public fun Path.relativeTo(base: Path): Path = try {
* @return Path with relative path from [base] to this, or `this` if this and base paths have different roots.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
public fun Path.relativeToOrSelf(base: Path): Path =
relativeToOrNull(base) ?: this
@@ -80,7 +80,7 @@ public fun Path.relativeToOrSelf(base: Path): Path =
* @return Path with relative path from [base] to this, or `null` if this and base paths have different roots.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
public fun Path.relativeToOrNull(base: Path): Path? = try {
PathRelativizer.tryRelativeTo(this, base)
} catch (e: IllegalArgumentException) {
@@ -143,7 +143,7 @@ internal object PathRelativizer {
* @throws IOException if any errors occur while copying.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
public fun Path.copyTo(target: Path, overwrite: Boolean = false): Path {
val options = if (overwrite) arrayOf(StandardCopyOption.REPLACE_EXISTING) else emptyArray()
return copyTo(target, *options)
@@ -179,7 +179,7 @@ public fun Path.copyTo(target: Path, overwrite: Boolean = false): Path {
* @throws IOException if any errors occur while copying.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
public fun Path.copyTo(target: Path, vararg options: CopyOption): Path {
return Files.copy(this, target, *options)
}
@@ -190,7 +190,7 @@ public fun Path.copyTo(target: Path, vararg options: CopyOption): Path {
* @param options Options to control how symbolic links are handled.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
@kotlin.internal.InlineOnly
public inline fun Path.exists(vararg options: LinkOption): Boolean = Files.exists(this, *options)
@@ -200,7 +200,7 @@ public inline fun Path.exists(vararg options: LinkOption): Boolean = Files.exist
* @param options Options to control how symbolic links are handled.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
@kotlin.internal.InlineOnly
public inline fun Path.notExists(vararg options: LinkOption): Boolean = Files.notExists(this, *options)
@@ -210,7 +210,7 @@ public inline fun Path.notExists(vararg options: LinkOption): Boolean = Files.no
* @param options Options to control how symbolic links are handled.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
@kotlin.internal.InlineOnly
public inline fun Path.isRegularFile(vararg options: LinkOption): Boolean = Files.isRegularFile(this, *options)
@@ -222,7 +222,7 @@ public inline fun Path.isRegularFile(vararg options: LinkOption): Boolean = File
* @param options Options to control how symbolic links are handled.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
@kotlin.internal.InlineOnly
public inline fun Path.isDirectory(vararg options: LinkOption): Boolean = Files.isDirectory(this, *options)
@@ -230,7 +230,7 @@ public inline fun Path.isDirectory(vararg options: LinkOption): Boolean = Files.
* Check if this path exists and is a symbolic link.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
@kotlin.internal.InlineOnly
public inline fun Path.isSymbolicLink(): Boolean = Files.isSymbolicLink(this)
@@ -238,7 +238,7 @@ public inline fun Path.isSymbolicLink(): Boolean = Files.isSymbolicLink(this)
* Check if this path exists and is executable.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
@kotlin.internal.InlineOnly
public inline fun Path.isExecutable(): Boolean = Files.isExecutable(this)
@@ -249,7 +249,7 @@ public inline fun Path.isExecutable(): Boolean = Files.isExecutable(this)
* path is considered hidden if its name begins with a dot. On Windows, file attributes are checked.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
@kotlin.internal.InlineOnly
public inline fun Path.isHidden(): Boolean = Files.isHidden(this)
@@ -257,7 +257,7 @@ public inline fun Path.isHidden(): Boolean = Files.isHidden(this)
* Check if this path exists and is readable.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
@kotlin.internal.InlineOnly
public inline fun Path.isReadable(): Boolean = Files.isReadable(this)
@@ -265,7 +265,7 @@ public inline fun Path.isReadable(): Boolean = Files.isReadable(this)
* Check that this path exists and is writable.
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
@kotlin.internal.InlineOnly
public inline fun Path.isWritable(): Boolean = Files.isWritable(this)
@@ -273,7 +273,7 @@ public inline fun Path.isWritable(): Boolean = Files.isWritable(this)
* Check if this path points to the same file or directory as [other].
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
@kotlin.internal.InlineOnly
public inline fun Path.isSameFile(other: Path): Boolean = Files.isSameFile(this, other)
@@ -284,7 +284,7 @@ public inline fun Path.isSameFile(other: Path): Boolean = Files.isSameFile(this,
* @throws IOException If an I/O error occurs
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
public fun Path.listDirectoryEntries(): List<Path> {
return Files.newDirectoryStream(this).use { it.toList() }
}
@@ -297,7 +297,7 @@ public fun Path.listDirectoryEntries(): List<Path> {
* @return the value returned by [block]
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
public fun <T> Path.useDirectoryEntries(block: (Sequence<Path>) -> T): T {
return Files.newDirectoryStream(this).use { block(it.asSequence()) }
}
@@ -309,7 +309,7 @@ public fun <T> Path.useDirectoryEntries(block: (Sequence<Path>) -> T): T {
* @throws IOException If an I/O error occurs
*/
@SinceKotlin("1.4")
@ExperimentalStdlibApi
@ExperimentalPathApi
public fun Path.forEachDirectoryEntry(action: (Path) -> Unit) {
return Files.newDirectoryStream(this).use { it.forEach(action) }
}
+1
View File
@@ -81,6 +81,7 @@ compileTestKotlin {
"-Xopt-in=kotlin.RequiresOptIn",
"-Xopt-in=kotlin.ExperimentalUnsignedTypes",
"-Xopt-in=kotlin.ExperimentalStdlibApi",
"-Xopt-in=kotlin.io.path.ExperimentalPathApi",
]
}