diff --git a/build.gradle.kts b/build.gradle.kts index 87fa032d5..8d71233d7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -94,11 +94,7 @@ tasks.withType().configur subprojects { tasks.withType>().configureEach { - if (name.contains("Test") || name.contains("Jmh")) { - compilerOptions.freeCompilerArgs.addAll(experimentalsInTestEnabled) - } else { - compilerOptions.freeCompilerArgs.addAll(experimentalsEnabled) - } + compilerOptions.freeCompilerArgs.addAll(globalCompilerArgs) } } @@ -172,18 +168,8 @@ gradle.taskGraph.whenReady { // getters are required because of variable lazy initialization in Gradle val unpublishedProjects get() = setOf("benchmark", "guide", "kotlinx-serialization-json-tests") val excludedFromBomProjects get() = unpublishedProjects + "kotlinx-serialization-bom" -val experimentalsEnabled get() = listOf( - "-progressive", - "-opt-in=kotlin.ExperimentalMultiplatform", - "-opt-in=kotlinx.serialization.InternalSerializationApi", - "-P", "plugin:org.jetbrains.kotlinx.serialization:disableIntrinsic=false" -) - -val experimentalsInTestEnabled get() = listOf( - "-progressive", - "-opt-in=kotlin.ExperimentalMultiplatform", - "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", - "-opt-in=kotlinx.serialization.InternalSerializationApi", +val globalCompilerArgs + get() = listOf( "-P", "plugin:org.jetbrains.kotlinx.serialization:disableIntrinsic=false" ) diff --git a/core/commonMain/src/kotlinx/serialization/Annotations.kt b/core/commonMain/src/kotlinx/serialization/Annotations.kt index 132b64414..c1a0835c6 100644 --- a/core/commonMain/src/kotlinx/serialization/Annotations.kt +++ b/core/commonMain/src/kotlinx/serialization/Annotations.kt @@ -341,8 +341,9 @@ public annotation class Polymorphic * Annotation is not allowed on classes involved in polymorphic serialization: * interfaces, sealed classes, abstract classes, classes marked by [Polymorphic]. * - * A compiler version `2.0.20` and higher is required. + * A compiler version `2.0.20` or higher is required. */ +@ExperimentalSerializationApi @Target(AnnotationTarget.CLASS) @Retention(AnnotationRetention.RUNTIME) public annotation class KeepGeneratedSerializer diff --git a/docs/basic-serialization.md b/docs/basic-serialization.md index 96e709817..ce98f4934 100644 --- a/docs/basic-serialization.md +++ b/docs/basic-serialization.md @@ -450,6 +450,7 @@ For that purposes, [EncodeDefault] annotation can be used: ```kotlin @Serializable +@OptIn(ExperimentalSerializationApi::class) // EncodeDefault is an experimental annotation for now data class Project( val name: String, @EncodeDefault val language: String = "Kotlin" @@ -462,6 +463,7 @@ It's also possible to tweak it into the opposite behavior using [EncodeDefault.M ```kotlin @Serializable +@OptIn(ExperimentalSerializationApi::class) // EncodeDefault is an experimental annotation for now data class User( val name: String, @EncodeDefault(EncodeDefault.Mode.NEVER) val projects: List = emptyList() diff --git a/docs/formats.md b/docs/formats.md index a6537e3bc..307601234 100644 --- a/docs/formats.md +++ b/docs/formats.md @@ -65,6 +65,7 @@ fun ByteArray.toAsciiHexString() = joinToString("") { @Serializable data class Project(val name: String, val language: String) +@OptIn(ExperimentalSerializationApi::class) fun main() { val data = Project("kotlinx.serialization", "Kotlin") val bytes = Cbor.encodeToByteArray(data) @@ -116,13 +117,14 @@ import kotlinx.serialization.cbor.* --> ```kotlin -val format = Cbor { ignoreUnknownKeys = true } - @Serializable data class Project(val name: String) +@OptIn(ExperimentalSerializationApi::class) fun main() { - val data = format.decodeFromHexString( + val format = Cbor { ignoreUnknownKeys = true } + + val data = format.decodeFromHexString( "bf646e616d65756b6f746c696e782e73657269616c697a6174696f6e686c616e6775616765664b6f746c696eff" ) println(data) @@ -183,12 +185,14 @@ fun ByteArray.toAsciiHexString() = joinToString("") { ```kotlin @Serializable +@OptIn(ExperimentalSerializationApi::class) data class Data( @ByteString val type2: ByteArray, // CBOR Major type 2 val type4: ByteArray // CBOR Major type 4 -) +) +@OptIn(ExperimentalSerializationApi::class) fun main() { val data = Data(byteArrayOf(1, 2, 3, 4), byteArrayOf(5, 6, 7, 8)) val bytes = Cbor.encodeToByteArray(data) @@ -338,6 +342,7 @@ fun ByteArray.toAsciiHexString() = joinToString("") { @Serializable data class Project(val name: String, val language: String) +@OptIn(ExperimentalSerializationApi::class) fun main() { val data = Project("kotlinx.serialization", "Kotlin") val bytes = ProtoBuf.encodeToByteArray(data) @@ -380,6 +385,7 @@ fun ByteArray.toAsciiHexString() = joinToString("") { --> ```kotlin +@OptIn(ExperimentalSerializationApi::class) @Serializable data class Project( @ProtoNumber(1) @@ -388,6 +394,7 @@ data class Project( val language: String ) +@OptIn(ExperimentalSerializationApi::class) fun main() { val data = Project("kotlinx.serialization", "Kotlin") val bytes = ProtoBuf.encodeToByteArray(data) @@ -432,6 +439,7 @@ fun ByteArray.toAsciiHexString() = joinToString("") { --> ```kotlin +@OptIn(ExperimentalSerializationApi::class) @Serializable class Data( @ProtoType(ProtoIntegerType.DEFAULT) @@ -442,6 +450,7 @@ class Data( val c: Int ) +@OptIn(ExperimentalSerializationApi::class) fun main() { val data = Data(1, -2, 3) println(ProtoBuf.encodeToByteArray(data).toAsciiHexString()) @@ -497,6 +506,7 @@ data class Data( val b: List = emptyList() ) +@OptIn(ExperimentalSerializationApi::class) fun main() { val data = Data(listOf(1, 2, 3), listOf()) val bytes = ProtoBuf.encodeToByteArray(data) @@ -561,6 +571,7 @@ import kotlinx.serialization.protobuf.* ```kotlin // The outer class +@OptIn(ExperimentalSerializationApi::class) @Serializable data class Data( @ProtoNumber(1) val name: String, @@ -571,11 +582,14 @@ data class Data( @Serializable sealed interface IPhoneType // Message holder for home_phone +@OptIn(ExperimentalSerializationApi::class) @Serializable @JvmInline value class HomePhone(@ProtoNumber(2) val number: String): IPhoneType // Message holder for work_phone. Can also be a value class, but we leave it as `data` to demonstrate that both variants can be used. +@OptIn(ExperimentalSerializationApi::class) @Serializable data class WorkPhone(@ProtoNumber(3) val number: String): IPhoneType +@OptIn(ExperimentalSerializationApi::class) fun main() { val dataTom = Data("Tom", HomePhone("123")) val stringTom = ProtoBuf.encodeToHexString(dataTom) @@ -654,6 +668,8 @@ data class SampleData( val description: String?, val department: String = "QA" ) + +@OptIn(ExperimentalSerializationApi::class) fun main() { val descriptors = listOf(SampleData.serializer().descriptor) val schemas = ProtoBufSchemaGenerator.generateSchemaText(descriptors) @@ -705,6 +721,7 @@ class Project(val name: String, val owner: User) @Serializable class User(val name: String) +@OptIn(ExperimentalSerializationApi::class) fun main() { val data = Project("kotlinx.serialization", User("kotlin")) val map = Properties.encodeToMap(data) @@ -737,7 +754,8 @@ implemented to get a basic working format. Let us start with a trivial format implementation that encodes the data into a single list of primitive constituent objects in the order they were written in the source code. To start, we implement a simple [Encoder] by -overriding `encodeValue` in [AbstractEncoder]. +overriding `encodeValue` in [AbstractEncoder]. Since encoders are intended to be consumed by other parts of application, +it is recommended to propagate the `@ExperimentalSerializationApi` annotation instead of opting-in. ```kotlin +@ExperimentalSerializationApi class ListEncoder : AbstractEncoder() { val list = mutableListOf() @@ -762,6 +781,7 @@ Now we write a convenience top-level function that creates an encoder that encod and returns a list. ```kotlin +@ExperimentalSerializationApi fun encodeToList(serializer: SerializationStrategy, value: T): List { val encoder = ListEncoder() encoder.encodeSerializableValue(serializer, value) @@ -774,6 +794,7 @@ the `encodeToList` function with a `reified` type parameter using the [serialize the appropriate [KSerializer] instance for the actual type. ```kotlin +@ExperimentalSerializationApi inline fun encodeToList(value: T) = encodeToList(serializer(), value) ``` @@ -786,6 +807,7 @@ data class Project(val name: String, val owner: User, val votes: Int) @Serializable data class User(val name: String) +@OptIn(ExperimentalSerializationApi::class) fun main() { val data = Project("kotlinx.serialization", User("kotlin"), 9000) println(encodeToList(data)) @@ -814,6 +836,7 @@ import kotlinx.serialization.descriptors.* import kotlinx.serialization.encoding.* import kotlinx.serialization.modules.* +@ExperimentalSerializationApi class ListEncoder : AbstractEncoder() { val list = mutableListOf() @@ -824,12 +847,14 @@ class ListEncoder : AbstractEncoder() { } } +@ExperimentalSerializationApi fun encodeToList(serializer: SerializationStrategy, value: T): List { val encoder = ListEncoder() encoder.encodeSerializableValue(serializer, value) return encoder.list } +@ExperimentalSerializationApi inline fun encodeToList(value: T) = encodeToList(serializer(), value) --> @@ -845,6 +870,7 @@ A decoder needs to implement more substance. each structure that is being recursively decoded keeps track of its own `elementIndex` state separately. ```kotlin +@ExperimentalSerializationApi class ListDecoder(val list: ArrayDeque) : AbstractDecoder() { private var elementIndex = 0 @@ -865,11 +891,13 @@ class ListDecoder(val list: ArrayDeque) : AbstractDecoder() { A couple of convenience functions for decoding. ```kotlin +@ExperimentalSerializationApi fun decodeFromList(list: List, deserializer: DeserializationStrategy): T { val decoder = ListDecoder(ArrayDeque(list)) return decoder.decodeSerializableValue(deserializer) } +@ExperimentalSerializationApi inline fun decodeFromList(list: List): T = decodeFromList(list, serializer()) ``` @@ -885,6 +913,7 @@ data class User(val name: String) --> ```kotlin +@OptIn(ExperimentalSerializationApi::class) fun main() { val data = Project("kotlinx.serialization", User("kotlin"), 9000) val list = encodeToList(data) @@ -922,6 +951,7 @@ import kotlinx.serialization.descriptors.* import kotlinx.serialization.encoding.* import kotlinx.serialization.modules.* +@ExperimentalSerializationApi class ListEncoder : AbstractEncoder() { val list = mutableListOf() @@ -932,16 +962,19 @@ class ListEncoder : AbstractEncoder() { } } +@ExperimentalSerializationApi fun encodeToList(serializer: SerializationStrategy, value: T): List { val encoder = ListEncoder() encoder.encodeSerializableValue(serializer, value) return encoder.list } +@ExperimentalSerializationApi inline fun encodeToList(value: T) = encodeToList(serializer(), value) --> ```kotlin +@ExperimentalSerializationApi class ListDecoder(val list: ArrayDeque) : AbstractDecoder() { private var elementIndex = 0 @@ -963,11 +996,13 @@ class ListDecoder(val list: ArrayDeque) : AbstractDecoder() { ```kotlin +@ExperimentalSerializationApi class ListEncoder : AbstractEncoder() { val list = mutableListOf() @@ -1027,12 +1064,14 @@ class ListEncoder : AbstractEncoder() { @@ -1042,6 +1081,7 @@ in addition to the previous code. > The formats that store collection size in advance have to return `true` from `decodeSequentially`. ```kotlin +@ExperimentalSerializationApi class ListDecoder(val list: ArrayDeque, var elementsCount: Int = 0) : AbstractDecoder() { private var elementIndex = 0 @@ -1066,11 +1106,13 @@ class ListDecoder(val list: ArrayDeque, var elementsCount: Int = 0) : Abstr @@ -1083,6 +1125,7 @@ data class Project(val name: String, val owners: List, val votes: Int) @Serializable data class User(val name: String) +@OptIn(ExperimentalSerializationApi::class) fun main() { val data = Project("kotlinx.serialization", listOf(User("kotlin"), User("jetbrains")), 9000) val list = encodeToList(data) @@ -1114,6 +1157,7 @@ import kotlinx.serialization.descriptors.* import kotlinx.serialization.encoding.* import kotlinx.serialization.modules.* +@ExperimentalSerializationApi class ListEncoder : AbstractEncoder() { val list = mutableListOf() @@ -1139,14 +1183,17 @@ In the encoder implementation we override [Encoder.encodeNull] and [Encoder.enco @@ -1194,6 +1243,7 @@ data class Project(val name: String, val owner: User?, val votes: Int?) @Serializable data class User(val name: String) +@OptIn(ExperimentalSerializationApi::class) fun main() { val data = Project("kotlinx.serialization", User("kotlin") , null) val list = encodeToList(data) @@ -1230,7 +1280,8 @@ import kotlinx.serialization.modules.* import java.io.* --> -```kotlin +```kotlin +@ExperimentalSerializationApi class DataOutputEncoder(val output: DataOutput) : AbstractEncoder() { override val serializersModule: SerializersModule = EmptySerializersModule() override fun encodeBoolean(value: Boolean) = output.writeByte(if (value) 1 else 0) @@ -1256,17 +1307,20 @@ class DataOutputEncoder(val output: DataOutput) : AbstractEncoder() { The decoder implementation mirrors encoder's implementation overriding all the primitive `decodeXxx` functions. ```kotlin +@ExperimentalSerializationApi class DataInputDecoder(val input: DataInput, var elementsCount: Int = 0) : AbstractDecoder() { private var elementIndex = 0 override val serializersModule: SerializersModule = EmptySerializersModule() @@ -1300,11 +1354,13 @@ class DataInputDecoder(val input: DataInput, var elementsCount: Int = 0) : Abstr ```kotlin +@OptIn(ExperimentalSerializationApi::class) @KeepGeneratedSerializer @Serializable(with = ColorAsStringSerializer::class) class Color(val rgb: Int) @@ -1170,7 +1175,8 @@ using the [Serializer] annotation on an object with the [`forClass`][Serializer. ```kotlin // NOT @Serializable class Project(val name: String, val language: String) - + +@OptIn(ExperimentalSerializationApi::class) @Serializer(forClass = Project::class) object ProjectSerializer ``` @@ -1215,8 +1221,9 @@ class Project( get() = "kotlin/$name" private var locked: Boolean = false // private, not accessible -- not serialized -} +} +@OptIn(ExperimentalSerializationApi::class) @Serializer(forClass = Project::class) object ProjectSerializer diff --git a/formats/hocon/build.gradle.kts b/formats/hocon/build.gradle.kts index 71a02fcbf..e2670528e 100644 --- a/formats/hocon/build.gradle.kts +++ b/formats/hocon/build.gradle.kts @@ -14,6 +14,7 @@ plugins { kotlin { jvmToolchain(jdkToolchainVersion) + compilerOptions { jvmTarget = JvmTarget.JVM_1_8 if (overriddenLanguageVersion != null) { @@ -22,6 +23,14 @@ kotlin { } freeCompilerArgs.add("-Xjdk-release=1.8") } + + sourceSets.all { + languageSettings { + progressiveMode = true + + optIn("kotlinx.serialization.InternalSerializationApi") + } + } } // Only main diff --git a/guide/build.gradle.kts b/guide/build.gradle.kts index a69992b50..5bafa9bb2 100644 --- a/guide/build.gradle.kts +++ b/guide/build.gradle.kts @@ -14,6 +14,7 @@ kotlin { jvmToolchain(8) compilerOptions { + allWarningsAsErrors = true if (overriddenLanguageVersion != null) { languageVersion = KotlinVersion.fromVersion(overriddenLanguageVersion!!) freeCompilerArgs.add("-Xsuppress-version-warnings") diff --git a/guide/example/example-classes-10.kt b/guide/example/example-classes-10.kt index c5a1f739c..941bde468 100644 --- a/guide/example/example-classes-10.kt +++ b/guide/example/example-classes-10.kt @@ -5,6 +5,7 @@ import kotlinx.serialization.* import kotlinx.serialization.json.* @Serializable +@OptIn(ExperimentalSerializationApi::class) // EncodeDefault is an experimental annotation for now data class Project( val name: String, @EncodeDefault val language: String = "Kotlin" @@ -12,6 +13,7 @@ data class Project( @Serializable +@OptIn(ExperimentalSerializationApi::class) // EncodeDefault is an experimental annotation for now data class User( val name: String, @EncodeDefault(EncodeDefault.Mode.NEVER) val projects: List = emptyList() diff --git a/guide/example/example-formats-01.kt b/guide/example/example-formats-01.kt index ad2b3e6d7..446bc3a34 100644 --- a/guide/example/example-formats-01.kt +++ b/guide/example/example-formats-01.kt @@ -12,6 +12,7 @@ fun ByteArray.toAsciiHexString() = joinToString("") { @Serializable data class Project(val name: String, val language: String) +@OptIn(ExperimentalSerializationApi::class) fun main() { val data = Project("kotlinx.serialization", "Kotlin") val bytes = Cbor.encodeToByteArray(data) diff --git a/guide/example/example-formats-02.kt b/guide/example/example-formats-02.kt index c95e53294..cddccf691 100644 --- a/guide/example/example-formats-02.kt +++ b/guide/example/example-formats-02.kt @@ -4,13 +4,14 @@ package example.exampleFormats02 import kotlinx.serialization.* import kotlinx.serialization.cbor.* -val format = Cbor { ignoreUnknownKeys = true } - @Serializable data class Project(val name: String) +@OptIn(ExperimentalSerializationApi::class) fun main() { - val data = format.decodeFromHexString( + val format = Cbor { ignoreUnknownKeys = true } + + val data = format.decodeFromHexString( "bf646e616d65756b6f746c696e782e73657269616c697a6174696f6e686c616e6775616765664b6f746c696eff" ) println(data) diff --git a/guide/example/example-formats-03.kt b/guide/example/example-formats-03.kt index d2191f6a0..b48811d6f 100644 --- a/guide/example/example-formats-03.kt +++ b/guide/example/example-formats-03.kt @@ -10,12 +10,14 @@ fun ByteArray.toAsciiHexString() = joinToString("") { } @Serializable +@OptIn(ExperimentalSerializationApi::class) data class Data( @ByteString val type2: ByteArray, // CBOR Major type 2 val type4: ByteArray // CBOR Major type 4 -) +) +@OptIn(ExperimentalSerializationApi::class) fun main() { val data = Data(byteArrayOf(1, 2, 3, 4), byteArrayOf(5, 6, 7, 8)) val bytes = Cbor.encodeToByteArray(data) diff --git a/guide/example/example-formats-04.kt b/guide/example/example-formats-04.kt index 9f6610bc1..0ff0289fe 100644 --- a/guide/example/example-formats-04.kt +++ b/guide/example/example-formats-04.kt @@ -12,6 +12,7 @@ fun ByteArray.toAsciiHexString() = joinToString("") { @Serializable data class Project(val name: String, val language: String) +@OptIn(ExperimentalSerializationApi::class) fun main() { val data = Project("kotlinx.serialization", "Kotlin") val bytes = ProtoBuf.encodeToByteArray(data) diff --git a/guide/example/example-formats-05.kt b/guide/example/example-formats-05.kt index 796e3eb07..b65e1cd1e 100644 --- a/guide/example/example-formats-05.kt +++ b/guide/example/example-formats-05.kt @@ -9,6 +9,7 @@ fun ByteArray.toAsciiHexString() = joinToString("") { "{${it.toUByte().toString(16).padStart(2, '0').uppercase()}}" } +@OptIn(ExperimentalSerializationApi::class) @Serializable data class Project( @ProtoNumber(1) @@ -17,6 +18,7 @@ data class Project( val language: String ) +@OptIn(ExperimentalSerializationApi::class) fun main() { val data = Project("kotlinx.serialization", "Kotlin") val bytes = ProtoBuf.encodeToByteArray(data) diff --git a/guide/example/example-formats-06.kt b/guide/example/example-formats-06.kt index 5e4fbc501..d675df117 100644 --- a/guide/example/example-formats-06.kt +++ b/guide/example/example-formats-06.kt @@ -9,6 +9,7 @@ fun ByteArray.toAsciiHexString() = joinToString("") { "{${it.toUByte().toString(16).padStart(2, '0').uppercase()}}" } +@OptIn(ExperimentalSerializationApi::class) @Serializable class Data( @ProtoType(ProtoIntegerType.DEFAULT) @@ -19,6 +20,7 @@ class Data( val c: Int ) +@OptIn(ExperimentalSerializationApi::class) fun main() { val data = Data(1, -2, 3) println(ProtoBuf.encodeToByteArray(data).toAsciiHexString()) diff --git a/guide/example/example-formats-07.kt b/guide/example/example-formats-07.kt index 52bc826b7..c219b8ddc 100644 --- a/guide/example/example-formats-07.kt +++ b/guide/example/example-formats-07.kt @@ -15,6 +15,7 @@ data class Data( val b: List = emptyList() ) +@OptIn(ExperimentalSerializationApi::class) fun main() { val data = Data(listOf(1, 2, 3), listOf()) val bytes = ProtoBuf.encodeToByteArray(data) diff --git a/guide/example/example-formats-08.kt b/guide/example/example-formats-08.kt index 1316aa0d3..23f3ccf31 100644 --- a/guide/example/example-formats-08.kt +++ b/guide/example/example-formats-08.kt @@ -5,6 +5,7 @@ import kotlinx.serialization.* import kotlinx.serialization.protobuf.* // The outer class +@OptIn(ExperimentalSerializationApi::class) @Serializable data class Data( @ProtoNumber(1) val name: String, @@ -15,11 +16,14 @@ data class Data( @Serializable sealed interface IPhoneType // Message holder for home_phone +@OptIn(ExperimentalSerializationApi::class) @Serializable @JvmInline value class HomePhone(@ProtoNumber(2) val number: String): IPhoneType // Message holder for work_phone. Can also be a value class, but we leave it as `data` to demonstrate that both variants can be used. +@OptIn(ExperimentalSerializationApi::class) @Serializable data class WorkPhone(@ProtoNumber(3) val number: String): IPhoneType +@OptIn(ExperimentalSerializationApi::class) fun main() { val dataTom = Data("Tom", HomePhone("123")) val stringTom = ProtoBuf.encodeToHexString(dataTom) diff --git a/guide/example/example-formats-09.kt b/guide/example/example-formats-09.kt index 387061f08..8c1ee2238 100644 --- a/guide/example/example-formats-09.kt +++ b/guide/example/example-formats-09.kt @@ -11,6 +11,8 @@ data class SampleData( val description: String?, val department: String = "QA" ) + +@OptIn(ExperimentalSerializationApi::class) fun main() { val descriptors = listOf(SampleData.serializer().descriptor) val schemas = ProtoBufSchemaGenerator.generateSchemaText(descriptors) diff --git a/guide/example/example-formats-10.kt b/guide/example/example-formats-10.kt index 020f175da..6941e4597 100644 --- a/guide/example/example-formats-10.kt +++ b/guide/example/example-formats-10.kt @@ -11,6 +11,7 @@ class Project(val name: String, val owner: User) @Serializable class User(val name: String) +@OptIn(ExperimentalSerializationApi::class) fun main() { val data = Project("kotlinx.serialization", User("kotlin")) val map = Properties.encodeToMap(data) diff --git a/guide/example/example-formats-11.kt b/guide/example/example-formats-11.kt index 9fa4180d8..6b8ccd117 100644 --- a/guide/example/example-formats-11.kt +++ b/guide/example/example-formats-11.kt @@ -6,6 +6,7 @@ import kotlinx.serialization.descriptors.* import kotlinx.serialization.encoding.* import kotlinx.serialization.modules.* +@ExperimentalSerializationApi class ListEncoder : AbstractEncoder() { val list = mutableListOf() @@ -16,12 +17,14 @@ class ListEncoder : AbstractEncoder() { } } +@ExperimentalSerializationApi fun encodeToList(serializer: SerializationStrategy, value: T): List { val encoder = ListEncoder() encoder.encodeSerializableValue(serializer, value) return encoder.list } +@ExperimentalSerializationApi inline fun encodeToList(value: T) = encodeToList(serializer(), value) @Serializable @@ -30,6 +33,7 @@ data class Project(val name: String, val owner: User, val votes: Int) @Serializable data class User(val name: String) +@OptIn(ExperimentalSerializationApi::class) fun main() { val data = Project("kotlinx.serialization", User("kotlin"), 9000) println(encodeToList(data)) diff --git a/guide/example/example-formats-12.kt b/guide/example/example-formats-12.kt index 803f331e6..5f087d94d 100644 --- a/guide/example/example-formats-12.kt +++ b/guide/example/example-formats-12.kt @@ -6,6 +6,7 @@ import kotlinx.serialization.descriptors.* import kotlinx.serialization.encoding.* import kotlinx.serialization.modules.* +@ExperimentalSerializationApi class ListEncoder : AbstractEncoder() { val list = mutableListOf() @@ -16,14 +17,17 @@ class ListEncoder : AbstractEncoder() { } } +@ExperimentalSerializationApi fun encodeToList(serializer: SerializationStrategy, value: T): List { val encoder = ListEncoder() encoder.encodeSerializableValue(serializer, value) return encoder.list } +@ExperimentalSerializationApi inline fun encodeToList(value: T) = encodeToList(serializer(), value) +@ExperimentalSerializationApi class ListDecoder(val list: ArrayDeque) : AbstractDecoder() { private var elementIndex = 0 @@ -40,11 +44,13 @@ class ListDecoder(val list: ArrayDeque) : AbstractDecoder() { ListDecoder(list) } +@ExperimentalSerializationApi fun decodeFromList(list: List, deserializer: DeserializationStrategy): T { val decoder = ListDecoder(ArrayDeque(list)) return decoder.decodeSerializableValue(deserializer) } +@ExperimentalSerializationApi inline fun decodeFromList(list: List): T = decodeFromList(list, serializer()) @Serializable @@ -53,6 +59,7 @@ data class Project(val name: String, val owner: User, val votes: Int) @Serializable data class User(val name: String) +@OptIn(ExperimentalSerializationApi::class) fun main() { val data = Project("kotlinx.serialization", User("kotlin"), 9000) val list = encodeToList(data) diff --git a/guide/example/example-formats-13.kt b/guide/example/example-formats-13.kt index 568017765..f2915f645 100644 --- a/guide/example/example-formats-13.kt +++ b/guide/example/example-formats-13.kt @@ -6,6 +6,7 @@ import kotlinx.serialization.descriptors.* import kotlinx.serialization.encoding.* import kotlinx.serialization.modules.* +@ExperimentalSerializationApi class ListEncoder : AbstractEncoder() { val list = mutableListOf() @@ -16,14 +17,17 @@ class ListEncoder : AbstractEncoder() { } } +@ExperimentalSerializationApi fun encodeToList(serializer: SerializationStrategy, value: T): List { val encoder = ListEncoder() encoder.encodeSerializableValue(serializer, value) return encoder.list } +@ExperimentalSerializationApi inline fun encodeToList(value: T) = encodeToList(serializer(), value) +@ExperimentalSerializationApi class ListDecoder(val list: ArrayDeque) : AbstractDecoder() { private var elementIndex = 0 @@ -42,11 +46,13 @@ class ListDecoder(val list: ArrayDeque) : AbstractDecoder() { override fun decodeSequentially(): Boolean = true } +@ExperimentalSerializationApi fun decodeFromList(list: List, deserializer: DeserializationStrategy): T { val decoder = ListDecoder(ArrayDeque(list)) return decoder.decodeSerializableValue(deserializer) } +@ExperimentalSerializationApi inline fun decodeFromList(list: List): T = decodeFromList(list, serializer()) @Serializable @@ -55,6 +61,7 @@ data class Project(val name: String, val owner: User, val votes: Int) @Serializable data class User(val name: String) +@OptIn(ExperimentalSerializationApi::class) fun main() { val data = Project("kotlinx.serialization", User("kotlin"), 9000) val list = encodeToList(data) diff --git a/guide/example/example-formats-14.kt b/guide/example/example-formats-14.kt index 3f88d51ca..782022a2e 100644 --- a/guide/example/example-formats-14.kt +++ b/guide/example/example-formats-14.kt @@ -6,6 +6,7 @@ import kotlinx.serialization.descriptors.* import kotlinx.serialization.encoding.* import kotlinx.serialization.modules.* +@ExperimentalSerializationApi class ListEncoder : AbstractEncoder() { val list = mutableListOf() @@ -21,14 +22,17 @@ class ListEncoder : AbstractEncoder() { } } +@ExperimentalSerializationApi fun encodeToList(serializer: SerializationStrategy, value: T): List { val encoder = ListEncoder() encoder.encodeSerializableValue(serializer, value) return encoder.list } +@ExperimentalSerializationApi inline fun encodeToList(value: T) = encodeToList(serializer(), value) +@ExperimentalSerializationApi class ListDecoder(val list: ArrayDeque, var elementsCount: Int = 0) : AbstractDecoder() { private var elementIndex = 0 @@ -50,11 +54,13 @@ class ListDecoder(val list: ArrayDeque, var elementsCount: Int = 0) : Abstr decodeInt().also { elementsCount = it } } +@ExperimentalSerializationApi fun decodeFromList(list: List, deserializer: DeserializationStrategy): T { val decoder = ListDecoder(ArrayDeque(list)) return decoder.decodeSerializableValue(deserializer) } +@ExperimentalSerializationApi inline fun decodeFromList(list: List): T = decodeFromList(list, serializer()) @Serializable @@ -63,6 +69,7 @@ data class Project(val name: String, val owners: List, val votes: Int) @Serializable data class User(val name: String) +@OptIn(ExperimentalSerializationApi::class) fun main() { val data = Project("kotlinx.serialization", listOf(User("kotlin"), User("jetbrains")), 9000) val list = encodeToList(data) diff --git a/guide/example/example-formats-15.kt b/guide/example/example-formats-15.kt index c48c18e4f..354ea1cba 100644 --- a/guide/example/example-formats-15.kt +++ b/guide/example/example-formats-15.kt @@ -6,6 +6,7 @@ import kotlinx.serialization.descriptors.* import kotlinx.serialization.encoding.* import kotlinx.serialization.modules.* +@ExperimentalSerializationApi class ListEncoder : AbstractEncoder() { val list = mutableListOf() @@ -24,14 +25,17 @@ class ListEncoder : AbstractEncoder() { override fun encodeNotNullMark() = encodeValue("!!") } +@ExperimentalSerializationApi fun encodeToList(serializer: SerializationStrategy, value: T): List { val encoder = ListEncoder() encoder.encodeSerializableValue(serializer, value) return encoder.list } +@ExperimentalSerializationApi inline fun encodeToList(value: T) = encodeToList(serializer(), value) +@ExperimentalSerializationApi class ListDecoder(val list: ArrayDeque, var elementsCount: Int = 0) : AbstractDecoder() { private var elementIndex = 0 @@ -55,11 +59,13 @@ class ListDecoder(val list: ArrayDeque, var elementsCount: Int = 0) : Abstr override fun decodeNotNullMark(): Boolean = decodeString() != "NULL" } +@ExperimentalSerializationApi fun decodeFromList(list: List, deserializer: DeserializationStrategy): T { val decoder = ListDecoder(ArrayDeque(list)) return decoder.decodeSerializableValue(deserializer) } +@ExperimentalSerializationApi inline fun decodeFromList(list: List): T = decodeFromList(list, serializer()) @Serializable @@ -68,6 +74,7 @@ data class Project(val name: String, val owner: User?, val votes: Int?) @Serializable data class User(val name: String) +@OptIn(ExperimentalSerializationApi::class) fun main() { val data = Project("kotlinx.serialization", User("kotlin") , null) val list = encodeToList(data) diff --git a/guide/example/example-formats-16.kt b/guide/example/example-formats-16.kt index 5bf0e4451..7a93ce271 100644 --- a/guide/example/example-formats-16.kt +++ b/guide/example/example-formats-16.kt @@ -8,6 +8,7 @@ import kotlinx.serialization.encoding.* import kotlinx.serialization.modules.* import java.io.* +@ExperimentalSerializationApi class DataOutputEncoder(val output: DataOutput) : AbstractEncoder() { override val serializersModule: SerializersModule = EmptySerializersModule() override fun encodeBoolean(value: Boolean) = output.writeByte(if (value) 1 else 0) @@ -30,13 +31,16 @@ class DataOutputEncoder(val output: DataOutput) : AbstractEncoder() { override fun encodeNotNullMark() = encodeBoolean(true) } +@ExperimentalSerializationApi fun encodeTo(output: DataOutput, serializer: SerializationStrategy, value: T) { val encoder = DataOutputEncoder(output) encoder.encodeSerializableValue(serializer, value) } +@ExperimentalSerializationApi inline fun encodeTo(output: DataOutput, value: T) = encodeTo(output, serializer(), value) +@ExperimentalSerializationApi class DataInputDecoder(val input: DataInput, var elementsCount: Int = 0) : AbstractDecoder() { private var elementIndex = 0 override val serializersModule: SerializersModule = EmptySerializersModule() @@ -67,11 +71,13 @@ class DataInputDecoder(val input: DataInput, var elementsCount: Int = 0) : Abstr override fun decodeNotNullMark(): Boolean = decodeBoolean() } +@ExperimentalSerializationApi fun decodeFrom(input: DataInput, deserializer: DeserializationStrategy): T { val decoder = DataInputDecoder(input) return decoder.decodeSerializableValue(deserializer) } +@ExperimentalSerializationApi inline fun decodeFrom(input: DataInput): T = decodeFrom(input, serializer()) fun ByteArray.toAsciiHexString() = joinToString("") { @@ -82,6 +88,7 @@ fun ByteArray.toAsciiHexString() = joinToString("") { @Serializable data class Project(val name: String, val language: String) +@OptIn(ExperimentalSerializationApi::class) fun main() { val data = Project("kotlinx.serialization", "Kotlin") val output = ByteArrayOutputStream() diff --git a/guide/example/example-formats-17.kt b/guide/example/example-formats-17.kt index 9a1c5a21d..ab16bf7e3 100644 --- a/guide/example/example-formats-17.kt +++ b/guide/example/example-formats-17.kt @@ -9,6 +9,7 @@ import kotlinx.serialization.encoding.* import java.io.* private val byteArraySerializer = serializer() +@ExperimentalSerializationApi class DataOutputEncoder(val output: DataOutput) : AbstractEncoder() { override val serializersModule: SerializersModule = EmptySerializersModule() override fun encodeBoolean(value: Boolean) = output.writeByte(if (value) 1 else 0) @@ -52,13 +53,16 @@ class DataOutputEncoder(val output: DataOutput) : AbstractEncoder() { } } +@ExperimentalSerializationApi fun encodeTo(output: DataOutput, serializer: SerializationStrategy, value: T) { val encoder = DataOutputEncoder(output) encoder.encodeSerializableValue(serializer, value) } +@ExperimentalSerializationApi inline fun encodeTo(output: DataOutput, value: T) = encodeTo(output, serializer(), value) +@ExperimentalSerializationApi class DataInputDecoder(val input: DataInput, var elementsCount: Int = 0) : AbstractDecoder() { private var elementIndex = 0 override val serializersModule: SerializersModule = EmptySerializersModule() @@ -108,11 +112,13 @@ class DataInputDecoder(val input: DataInput, var elementsCount: Int = 0) : Abstr } } +@ExperimentalSerializationApi fun decodeFrom(input: DataInput, deserializer: DeserializationStrategy): T { val decoder = DataInputDecoder(input) return decoder.decodeSerializableValue(deserializer) } +@ExperimentalSerializationApi inline fun decodeFrom(input: DataInput): T = decodeFrom(input, serializer()) fun ByteArray.toAsciiHexString() = joinToString("") { @@ -123,6 +129,7 @@ fun ByteArray.toAsciiHexString() = joinToString("") { @Serializable data class Project(val name: String, val attachment: ByteArray) +@OptIn(ExperimentalSerializationApi::class) fun main() { val data = Project("kotlinx.serialization", byteArrayOf(0x0A, 0x0B, 0x0C, 0x0D)) val output = ByteArrayOutputStream() diff --git a/guide/example/example-json-04.kt b/guide/example/example-json-04.kt index a8ae148cc..92d036728 100644 --- a/guide/example/example-json-04.kt +++ b/guide/example/example-json-04.kt @@ -4,6 +4,7 @@ package example.exampleJson04 import kotlinx.serialization.* import kotlinx.serialization.json.* +@OptIn(ExperimentalSerializationApi::class) // JsonNames is an experimental annotation for now @Serializable data class Project(@JsonNames("title") val name: String) diff --git a/guide/example/example-json-12.kt b/guide/example/example-json-12.kt index da76d4c39..f3f11a678 100644 --- a/guide/example/example-json-12.kt +++ b/guide/example/example-json-12.kt @@ -4,6 +4,7 @@ package example.exampleJson12 import kotlinx.serialization.* import kotlinx.serialization.json.* +@OptIn(ExperimentalSerializationApi::class) // JsonClassDiscriminator is an experimental annotation for now @Serializable @JsonClassDiscriminator("message_type") sealed class Base diff --git a/guide/example/example-json-13.kt b/guide/example/example-json-13.kt index 5da592e74..9794230c6 100644 --- a/guide/example/example-json-13.kt +++ b/guide/example/example-json-13.kt @@ -4,6 +4,7 @@ package example.exampleJson13 import kotlinx.serialization.* import kotlinx.serialization.json.* +@OptIn(ExperimentalSerializationApi::class) // classDiscriminatorMode is an experimental setting for now val format = Json { classDiscriminatorMode = ClassDiscriminatorMode.NONE } @Serializable diff --git a/guide/example/example-json-14.kt b/guide/example/example-json-14.kt index 67d2e2d32..f0def0e4b 100644 --- a/guide/example/example-json-14.kt +++ b/guide/example/example-json-14.kt @@ -4,8 +4,10 @@ package example.exampleJson14 import kotlinx.serialization.* import kotlinx.serialization.json.* +@OptIn(ExperimentalSerializationApi::class) // decodeEnumsCaseInsensitive is an experimental setting for now val format = Json { decodeEnumsCaseInsensitive = true } +@OptIn(ExperimentalSerializationApi::class) // JsonNames is an experimental annotation for now enum class Cases { VALUE_A, @JsonNames("Alternative") VALUE_B } @Serializable diff --git a/guide/example/example-json-15.kt b/guide/example/example-json-15.kt index db504cbff..267d5cc2e 100644 --- a/guide/example/example-json-15.kt +++ b/guide/example/example-json-15.kt @@ -7,6 +7,7 @@ import kotlinx.serialization.json.* @Serializable data class Project(val projectName: String, val projectOwner: String) +@OptIn(ExperimentalSerializationApi::class) // namingStrategy is an experimental setting for now val format = Json { namingStrategy = JsonNamingStrategy.SnakeCase } fun main() { diff --git a/guide/example/example-json-22.kt b/guide/example/example-json-22.kt index 952ca30cf..f334ce5f9 100644 --- a/guide/example/example-json-22.kt +++ b/guide/example/example-json-22.kt @@ -12,6 +12,7 @@ fun main() { val pi = BigDecimal("3.141592653589793238462643383279") // use JsonUnquotedLiteral to encode raw JSON content + @OptIn(ExperimentalSerializationApi::class) val piJsonLiteral = JsonUnquotedLiteral(pi.toString()) val piJsonDouble = JsonPrimitive(pi.toDouble()) diff --git a/guide/example/example-json-24.kt b/guide/example/example-json-24.kt index c9138d243..3452c6ce1 100644 --- a/guide/example/example-json-24.kt +++ b/guide/example/example-json-24.kt @@ -4,6 +4,7 @@ package example.exampleJson24 import kotlinx.serialization.* import kotlinx.serialization.json.* +@OptIn(ExperimentalSerializationApi::class) fun main() { // caution: creating null with JsonUnquotedLiteral will cause an exception! JsonUnquotedLiteral("null") diff --git a/guide/example/example-json-29.kt b/guide/example/example-json-29.kt index e72ca6135..41245ffb1 100644 --- a/guide/example/example-json-29.kt +++ b/guide/example/example-json-29.kt @@ -9,6 +9,7 @@ sealed class Project { abstract val name: String } +@OptIn(ExperimentalSerializationApi::class) @KeepGeneratedSerializer @Serializable(with = BasicProjectSerializer::class) @SerialName("basic") diff --git a/guide/example/example-json-30.kt b/guide/example/example-json-30.kt index 2c3ec3cb2..fe379dff6 100644 --- a/guide/example/example-json-30.kt +++ b/guide/example/example-json-30.kt @@ -14,7 +14,7 @@ sealed class Response { } class ResponseSerializer(private val dataSerializer: KSerializer) : KSerializer> { - override val descriptor: SerialDescriptor = buildSerialDescriptor("Response", PolymorphicKind.SEALED) { + override val descriptor: SerialDescriptor = buildClassSerialDescriptor("Response") { element("Ok", dataSerializer.descriptor) element("Error", buildClassSerialDescriptor("Error") { element("message") diff --git a/guide/example/example-serializer-10.kt b/guide/example/example-serializer-10.kt index 2b756524d..a69deceb4 100644 --- a/guide/example/example-serializer-10.kt +++ b/guide/example/example-serializer-10.kt @@ -10,6 +10,7 @@ import kotlinx.serialization.builtins.IntArraySerializer class ColorIntArraySerializer : KSerializer { private val delegateSerializer = IntArraySerializer() + @OptIn(ExperimentalSerializationApi::class) override val descriptor = SerialDescriptor("Color", delegateSerializer.descriptor) override fun serialize(encoder: Encoder, value: Color) { diff --git a/guide/example/example-serializer-13.kt b/guide/example/example-serializer-13.kt index f2b088828..8de0c8e52 100644 --- a/guide/example/example-serializer-13.kt +++ b/guide/example/example-serializer-13.kt @@ -26,7 +26,8 @@ object ColorAsObjectSerializer : KSerializer { decoder.decodeStructure(descriptor) { var r = -1 var g = -1 - var b = -1 + var b = -1 + @OptIn(ExperimentalSerializationApi::class) if (decodeSequentially()) { // sequential decoding protocol r = decodeIntElement(descriptor, 0) g = decodeIntElement(descriptor, 1) diff --git a/guide/example/example-serializer-20.kt b/guide/example/example-serializer-20.kt index 4d5cc991b..812c05b85 100644 --- a/guide/example/example-serializer-20.kt +++ b/guide/example/example-serializer-20.kt @@ -20,6 +20,7 @@ object ColorAsStringSerializer : KSerializer { } } +@OptIn(ExperimentalSerializationApi::class) @KeepGeneratedSerializer @Serializable(with = ColorAsStringSerializer::class) class Color(val rgb: Int) diff --git a/guide/example/example-serializer-23.kt b/guide/example/example-serializer-23.kt index 9f01476f0..78d537f50 100644 --- a/guide/example/example-serializer-23.kt +++ b/guide/example/example-serializer-23.kt @@ -8,7 +8,8 @@ import kotlinx.serialization.descriptors.* // NOT @Serializable class Project(val name: String, val language: String) - + +@OptIn(ExperimentalSerializationApi::class) @Serializer(forClass = Project::class) object ProjectSerializer diff --git a/guide/example/example-serializer-24.kt b/guide/example/example-serializer-24.kt index 99b0c2d7c..52b5be75e 100644 --- a/guide/example/example-serializer-24.kt +++ b/guide/example/example-serializer-24.kt @@ -17,8 +17,9 @@ class Project( get() = "kotlin/$name" private var locked: Boolean = false // private, not accessible -- not serialized -} +} +@OptIn(ExperimentalSerializationApi::class) @Serializer(forClass = Project::class) object ProjectSerializer