diff options
author | Leonid Startsev <sandwwraith@users.noreply.github.com> | 2023-09-21 14:46:24 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-21 14:46:24 +0200 |
commit | 7b75e39ae6837bfad04d0d18b24bd0facbf9e63c (patch) | |
tree | 1688c15a7d5c32771e52eccc974e8cbfd6cd6aa0 | |
parent | 7d287c84e83e6af4c5c0ecb27cd573db9d0cffd9 (diff) | |
download | kotlinx.serialization-7b75e39ae6837bfad04d0d18b24bd0facbf9e63c.tar.gz |
Get rid of @Suppress("INVISIBLE_REFERENCE") for usage of internal declarations (#2444)
* Introduce additional internal opt-in annotation to hide declarations even more
* Rename JsonWriter and SerialReader to something more internal-ish
* Refactor internal extensions on Json into top-level functions to remove them from completion (because even optable-in declarations are shown in completion for all users)
* Propagate opt-ins to verifyKotlinModule task
Related: https://youtrack.jetbrains.com/issue/KTIJ-27132
30 files changed, 152 insertions, 112 deletions
diff --git a/buildSrc/src/main/kotlin/Java9Modularity.kt b/buildSrc/src/main/kotlin/Java9Modularity.kt index 6c0bb523..161b90db 100644 --- a/buildSrc/src/main/kotlin/Java9Modularity.kt +++ b/buildSrc/src/main/kotlin/Java9Modularity.kt @@ -131,6 +131,7 @@ object Java9Modularity { // To support LV override when set in aggregate builds languageVersion = compileTask.kotlinOptions.languageVersion freeCompilerArgs += listOf("-Xjdk-release=9", "-Xsuppress-version-warnings") + options.optIn.addAll(compileTask.kotlinOptions.options.optIn) } // work-around for https://youtrack.jetbrains.com/issue/KT-60583 inputs.files( diff --git a/core/commonMain/src/kotlinx/serialization/internal/ElementMarker.kt b/core/commonMain/src/kotlinx/serialization/internal/ElementMarker.kt index fca90262..5e6736d3 100644 --- a/core/commonMain/src/kotlinx/serialization/internal/ElementMarker.kt +++ b/core/commonMain/src/kotlinx/serialization/internal/ElementMarker.kt @@ -4,13 +4,13 @@ package kotlinx.serialization.internal -import kotlinx.serialization.ExperimentalSerializationApi +import kotlinx.serialization.* import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.CompositeDecoder @OptIn(ExperimentalSerializationApi::class) -@PublishedApi -internal class ElementMarker( +@CoreFriendModuleApi +public class ElementMarker( private val descriptor: SerialDescriptor, // Instead of inheritance and virtual function in order to keep cross-module internal modifier via suppresses // Can be reworked via public + internal api if necessary @@ -45,7 +45,7 @@ internal class ElementMarker( } } - fun mark(index: Int) { + public fun mark(index: Int) { if (index < Long.SIZE_BITS) { lowerMarks = lowerMarks or (1L shl index) } else { @@ -53,7 +53,7 @@ internal class ElementMarker( } } - fun nextUnmarkedIndex(): Int { + public fun nextUnmarkedIndex(): Int { val elementsCount = descriptor.elementsCount while (lowerMarks != -1L) { val index = lowerMarks.inv().countTrailingZeroBits() diff --git a/core/commonMain/src/kotlinx/serialization/internal/JsonInternalDependencies.kt b/core/commonMain/src/kotlinx/serialization/internal/JsonInternalDependencies.kt index d79cb8b9..e733827f 100644 --- a/core/commonMain/src/kotlinx/serialization/internal/JsonInternalDependencies.kt +++ b/core/commonMain/src/kotlinx/serialization/internal/JsonInternalDependencies.kt @@ -1,14 +1,14 @@ package kotlinx.serialization.internal -import kotlinx.serialization.* import kotlinx.serialization.descriptors.* /* - * Methods that are required for kotlinx-serialization-json, but are not effectively public - * and actually represent our own technical debt. - * This methods are not intended for public use + * Methods that are required for kotlinx-serialization-json, but are not effectively public. + * + * Anything marker with this annotation is not intended for public use. */ +@RequiresOptIn(level = RequiresOptIn.Level.ERROR) +internal annotation class CoreFriendModuleApi -@InternalSerializationApi -@Deprecated(message = "Should not be used", level = DeprecationLevel.ERROR) +@CoreFriendModuleApi public fun SerialDescriptor.jsonCachedSerialNames(): Set<String> = cachedSerialNames() diff --git a/core/commonTest/src/kotlinx/serialization/ElementMarkerTest.kt b/core/commonTest/src/kotlinx/serialization/ElementMarkerTest.kt index a22be3ff..3fee5873 100644 --- a/core/commonTest/src/kotlinx/serialization/ElementMarkerTest.kt +++ b/core/commonTest/src/kotlinx/serialization/ElementMarkerTest.kt @@ -2,10 +2,11 @@ package kotlinx.serialization import kotlinx.serialization.descriptors.* import kotlinx.serialization.encoding.CompositeDecoder -import kotlinx.serialization.internal.ElementMarker +import kotlinx.serialization.internal.* import kotlin.test.Test import kotlin.test.assertEquals +@OptIn(CoreFriendModuleApi::class) class ElementMarkerTest { @Test fun testNothingWasRead() { diff --git a/formats/json-okio/build.gradle.kts b/formats/json-okio/build.gradle.kts index 6d90b77b..43859e4c 100644 --- a/formats/json-okio/build.gradle.kts +++ b/formats/json-okio/build.gradle.kts @@ -15,6 +15,12 @@ apply(from = rootProject.file("gradle/configure-source-sets.gradle")) kotlin { sourceSets { + configureEach { + languageSettings { + optIn("kotlinx.serialization.internal.CoreFriendModuleApi") + optIn("kotlinx.serialization.json.internal.JsonFriendModuleApi") + } + } val commonMain by getting { dependencies { api(project(":kotlinx-serialization-core")) @@ -58,4 +64,4 @@ if (isNewWasmTargetEnabled) { } } } -}
\ No newline at end of file +} diff --git a/formats/json-okio/commonMain/src/kotlinx/serialization/json/okio/OkioStreams.kt b/formats/json-okio/commonMain/src/kotlinx/serialization/json/okio/OkioStreams.kt index b827806e..968f5339 100644 --- a/formats/json-okio/commonMain/src/kotlinx/serialization/json/okio/OkioStreams.kt +++ b/formats/json-okio/commonMain/src/kotlinx/serialization/json/okio/OkioStreams.kt @@ -2,8 +2,6 @@ * Copyright 2017-2022 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. */ -@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER") - package kotlinx.serialization.json.okio import kotlinx.serialization.* @@ -29,7 +27,7 @@ public fun <T> Json.encodeToBufferedSink( ) { val writer = JsonToOkioStreamWriter(sink) try { - encodeByWriter(writer, serializer, value) + encodeByWriter(this, writer, serializer, value) } finally { writer.release() } @@ -62,7 +60,7 @@ public fun <T> Json.decodeFromBufferedSource( deserializer: DeserializationStrategy<T>, source: BufferedSource ): T { - return decodeByReader(deserializer, OkioSerialReader(source)) + return decodeByReader(this, deserializer, OkioSerialReader(source)) } /** @@ -101,7 +99,7 @@ public fun <T> Json.decodeBufferedSourceToSequence( deserializer: DeserializationStrategy<T>, format: DecodeSequenceMode = DecodeSequenceMode.AUTO_DETECT ): Sequence<T> { - return decodeToSequenceByReader(OkioSerialReader(source), deserializer, format) + return decodeToSequenceByReader(this, OkioSerialReader(source), deserializer, format) } /** diff --git a/formats/json-okio/commonMain/src/kotlinx/serialization/json/okio/internal/OkioJsonStreams.kt b/formats/json-okio/commonMain/src/kotlinx/serialization/json/okio/internal/OkioJsonStreams.kt index c2066788..1de89713 100644 --- a/formats/json-okio/commonMain/src/kotlinx/serialization/json/okio/internal/OkioJsonStreams.kt +++ b/formats/json-okio/commonMain/src/kotlinx/serialization/json/okio/internal/OkioJsonStreams.kt @@ -2,16 +2,39 @@ * Copyright 2017-2022 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. */ -@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER", "CANNOT_OVERRIDE_INVISIBLE_MEMBER") - package kotlinx.serialization.json.okio.internal -import kotlinx.serialization.json.internal.ESCAPE_STRINGS -import kotlinx.serialization.json.internal.JsonWriter -import kotlinx.serialization.json.internal.SerialReader +import kotlinx.serialization.json.internal.* import okio.* -internal class JsonToOkioStreamWriter(private val sink: BufferedSink) : JsonWriter { +// Copied from kotlinx/serialization/json/internal/StringOps.kt +private fun toHexChar(i: Int) : Char { + val d = i and 0xf + return if (d < 10) (d + '0'.code).toChar() + else (d - 10 + 'a'.code).toChar() +} + +// Copied from kotlinx/serialization/json/internal/StringOps.kt +private val ESCAPE_STRINGS: Array<String?> = arrayOfNulls<String>(93).apply { + for (c in 0..0x1f) { + val c1 = toHexChar(c shr 12) + val c2 = toHexChar(c shr 8) + val c3 = toHexChar(c shr 4) + val c4 = toHexChar(c) + this[c] = "\\u$c1$c2$c3$c4" + } + this['"'.code] = "\\\"" + this['\\'.code] = "\\\\" + this['\t'.code] = "\\t" + this['\b'.code] = "\\b" + this['\n'.code] = "\\n" + this['\r'.code] = "\\r" + this[0x0c] = "\\f" +} + + + +internal class JsonToOkioStreamWriter(private val sink: BufferedSink) : InternalJsonWriter { override fun writeLong(value: Long) { write(value.toString()) } @@ -54,7 +77,7 @@ private const val HIGH_SURROGATE_HEADER = 0xd800 - (0x010000 ushr 10) private const val LOW_SURROGATE_HEADER = 0xdc00 -internal class OkioSerialReader(private val source: BufferedSource): SerialReader { +internal class OkioSerialReader(private val source: BufferedSource): InternalJsonReader { /* A sequence of code points is read from UTF-8, some of it can take 2 characters. In case the last code point requires 2 characters, and the array is already full, we buffer the second character diff --git a/formats/json-tests/build.gradle.kts b/formats/json-tests/build.gradle.kts index 95b9e1c0..3c84e29d 100644 --- a/formats/json-tests/build.gradle.kts +++ b/formats/json-tests/build.gradle.kts @@ -25,6 +25,12 @@ tasks.named("koverVerify") { kotlin { sourceSets { + configureEach { + languageSettings { + optIn("kotlinx.serialization.internal.CoreFriendModuleApi") + optIn("kotlinx.serialization.json.internal.JsonFriendModuleApi") + } + } val commonTest by getting { dependencies { api(project(":kotlinx-serialization-json")) @@ -64,4 +70,4 @@ if (!isNewWasmTargetEnabled) { tasks.named("wasmD8Test", KotlinJsTest::class) { filter.excludePatterns += "kotlinx.serialization.features.EmojiTest" } -}
\ No newline at end of file +} diff --git a/formats/json-tests/commonTest/src/kotlinx/serialization/json/JsonTestBase.kt b/formats/json-tests/commonTest/src/kotlinx/serialization/json/JsonTestBase.kt index ebcc3d07..6f3b132e 100644 --- a/formats/json-tests/commonTest/src/kotlinx/serialization/json/JsonTestBase.kt +++ b/formats/json-tests/commonTest/src/kotlinx/serialization/json/JsonTestBase.kt @@ -49,7 +49,7 @@ abstract class JsonTestBase { encodeViaStream(serializer, value) } JsonTestingMode.TREE -> { - val tree = writeJson(value, serializer) + val tree = writeJson(this, value, serializer) encodeToString(tree) } JsonTestingMode.OKIO_STREAMS -> { @@ -77,8 +77,8 @@ abstract class JsonTestBase { decodeViaStream(deserializer, source) } JsonTestingMode.TREE -> { - val tree = decodeStringToJsonTree(deserializer, source) - readJson(tree, deserializer) + val tree = decodeStringToJsonTree(this, deserializer, source) + readJson(this, tree, deserializer) } JsonTestingMode.OKIO_STREAMS -> { val buffer = Buffer() diff --git a/formats/json/api/kotlinx-serialization-json.api b/formats/json/api/kotlinx-serialization-json.api index e6a2328d..bdc6bdff 100644 --- a/formats/json/api/kotlinx-serialization-json.api +++ b/formats/json/api/kotlinx-serialization-json.api @@ -383,14 +383,11 @@ public final class kotlinx/serialization/json/JvmStreamsKt { public static final fun encodeToStream (Lkotlinx/serialization/json/Json;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Ljava/io/OutputStream;)V } -public final class kotlinx/serialization/json/internal/JsonStreamsKt { - public static final fun decodeByReader (Lkotlinx/serialization/json/Json;Lkotlinx/serialization/DeserializationStrategy;Lkotlinx/serialization/json/internal/SerialReader;)Ljava/lang/Object; - public static final fun decodeToSequenceByReader (Lkotlinx/serialization/json/Json;Lkotlinx/serialization/json/internal/SerialReader;Lkotlinx/serialization/DeserializationStrategy;Lkotlinx/serialization/json/DecodeSequenceMode;)Lkotlin/sequences/Sequence; - public static synthetic fun decodeToSequenceByReader$default (Lkotlinx/serialization/json/Json;Lkotlinx/serialization/json/internal/SerialReader;Lkotlinx/serialization/DeserializationStrategy;Lkotlinx/serialization/json/DecodeSequenceMode;ILjava/lang/Object;)Lkotlin/sequences/Sequence; - public static final fun encodeByWriter (Lkotlinx/serialization/json/Json;Lkotlinx/serialization/json/internal/JsonWriter;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V +public abstract interface class kotlinx/serialization/json/internal/InternalJsonReader { + public abstract fun read ([CII)I } -public abstract interface class kotlinx/serialization/json/internal/JsonWriter { +public abstract interface class kotlinx/serialization/json/internal/InternalJsonWriter { public abstract fun release ()V public abstract fun write (Ljava/lang/String;)V public abstract fun writeChar (C)V @@ -398,18 +395,17 @@ public abstract interface class kotlinx/serialization/json/internal/JsonWriter { public abstract fun writeQuoted (Ljava/lang/String;)V } -public abstract interface class kotlinx/serialization/json/internal/SerialReader { - public abstract fun read ([CII)I +public final class kotlinx/serialization/json/internal/JsonStreamsKt { + public static final fun decodeByReader (Lkotlinx/serialization/json/Json;Lkotlinx/serialization/DeserializationStrategy;Lkotlinx/serialization/json/internal/InternalJsonReader;)Ljava/lang/Object; + public static final fun decodeToSequenceByReader (Lkotlinx/serialization/json/Json;Lkotlinx/serialization/json/internal/InternalJsonReader;Lkotlinx/serialization/DeserializationStrategy;Lkotlinx/serialization/json/DecodeSequenceMode;)Lkotlin/sequences/Sequence; + public static synthetic fun decodeToSequenceByReader$default (Lkotlinx/serialization/json/Json;Lkotlinx/serialization/json/internal/InternalJsonReader;Lkotlinx/serialization/DeserializationStrategy;Lkotlinx/serialization/json/DecodeSequenceMode;ILjava/lang/Object;)Lkotlin/sequences/Sequence; + public static final fun encodeByWriter (Lkotlinx/serialization/json/Json;Lkotlinx/serialization/json/internal/InternalJsonWriter;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V } public final class kotlinx/serialization/json/internal/StreamingJsonDecoderKt { public static final fun decodeStringToJsonTree (Lkotlinx/serialization/json/Json;Lkotlinx/serialization/DeserializationStrategy;Ljava/lang/String;)Lkotlinx/serialization/json/JsonElement; } -public final class kotlinx/serialization/json/internal/StringOpsKt { - public static final fun getESCAPE_STRINGS ()[Ljava/lang/String; -} - public final class kotlinx/serialization/json/internal/TreeJsonDecoderKt { public static final fun readJson (Lkotlinx/serialization/json/Json;Lkotlinx/serialization/json/JsonElement;Lkotlinx/serialization/DeserializationStrategy;)Ljava/lang/Object; } diff --git a/formats/json/build.gradle b/formats/json/build.gradle index 9b177ace..105c8dec 100644 --- a/formats/json/build.gradle +++ b/formats/json/build.gradle @@ -24,8 +24,13 @@ tasks.named("koverVerify") { def isNewWasmTargetEnabled = isKotlinVersionAtLeast(rootProject.properties["kotlin_version"], 1, 9, 20) kotlin { - sourceSets { + configureEach { + languageSettings { + optIn("kotlinx.serialization.internal.CoreFriendModuleApi") + optIn("kotlinx.serialization.json.internal.JsonFriendModuleApi") + } + } commonMain { dependencies { api project(":kotlinx-serialization-core") @@ -56,4 +61,4 @@ tasks.whenTaskAdded { task -> if (task.name == 'compileJsWasmMainKotlinMetadata') { task.enabled = false } -}
\ No newline at end of file +} diff --git a/formats/json/commonMain/src/kotlinx/serialization/json/Json.kt b/formats/json/commonMain/src/kotlinx/serialization/json/Json.kt index 40dcc23e..be7a7f08 100644 --- a/formats/json/commonMain/src/kotlinx/serialization/json/Json.kt +++ b/formats/json/commonMain/src/kotlinx/serialization/json/Json.kt @@ -78,7 +78,7 @@ public sealed class Json( public final override fun <T> encodeToString(serializer: SerializationStrategy<T>, value: T): String { val result = JsonToStringWriter() try { - encodeByWriter(result, serializer, value) + encodeByWriter(this@Json, result, serializer, value) return result.toString() } finally { result.release() @@ -114,7 +114,7 @@ public sealed class Json( * @throws [SerializationException] if the given value cannot be serialized to JSON */ public fun <T> encodeToJsonElement(serializer: SerializationStrategy<T>, value: T): JsonElement { - return writeJson(value, serializer) + return writeJson(this@Json, value, serializer) } /** @@ -124,7 +124,7 @@ public sealed class Json( * @throws [IllegalArgumentException] if the decoded input cannot be represented as a valid instance of type [T] */ public fun <T> decodeFromJsonElement(deserializer: DeserializationStrategy<T>, element: JsonElement): T { - return readJson(element, deserializer) + return readJson(this@Json, element, deserializer) } /** diff --git a/formats/json/commonMain/src/kotlinx/serialization/json/JsonTransformingSerializer.kt b/formats/json/commonMain/src/kotlinx/serialization/json/JsonTransformingSerializer.kt index 8d1485d6..22d87a72 100644 --- a/formats/json/commonMain/src/kotlinx/serialization/json/JsonTransformingSerializer.kt +++ b/formats/json/commonMain/src/kotlinx/serialization/json/JsonTransformingSerializer.kt @@ -67,7 +67,7 @@ public abstract class JsonTransformingSerializer<T : Any>( final override fun serialize(encoder: Encoder, value: T) { val output = encoder.asJsonEncoder() - var element = output.json.writeJson(value, tSerializer) + var element = writeJson(output.json, value, tSerializer) element = transformSerialize(element) output.encodeJsonElement(element) } diff --git a/formats/json/commonMain/src/kotlinx/serialization/json/internal/Composers.kt b/formats/json/commonMain/src/kotlinx/serialization/json/internal/Composers.kt index d5841552..c1ed8cca 100644 --- a/formats/json/commonMain/src/kotlinx/serialization/json/internal/Composers.kt +++ b/formats/json/commonMain/src/kotlinx/serialization/json/internal/Composers.kt @@ -9,11 +9,11 @@ import kotlinx.serialization.* import kotlinx.serialization.json.* import kotlin.jvm.* -internal fun Composer(sb: JsonWriter, json: Json): Composer = +internal fun Composer(sb: InternalJsonWriter, json: Json): Composer = if (json.configuration.prettyPrint) ComposerWithPrettyPrint(sb, json) else Composer(sb) @OptIn(ExperimentalSerializationApi::class) -internal open class Composer(@JvmField internal val writer: JsonWriter) { +internal open class Composer(@JvmField internal val writer: InternalJsonWriter) { var writingFirst = true protected set @@ -42,7 +42,7 @@ internal open class Composer(@JvmField internal val writer: JsonWriter) { } @SuppressAnimalSniffer // Long(Integer).toUnsignedString(long) -internal class ComposerForUnsignedNumbers(writer: JsonWriter, private val forceQuoting: Boolean) : Composer(writer) { +internal class ComposerForUnsignedNumbers(writer: InternalJsonWriter, private val forceQuoting: Boolean) : Composer(writer) { override fun print(v: Int) { if (forceQuoting) printQuoted(v.toUInt().toString()) else print(v.toUInt().toString()) } @@ -61,14 +61,14 @@ internal class ComposerForUnsignedNumbers(writer: JsonWriter, private val forceQ } @SuppressAnimalSniffer -internal class ComposerForUnquotedLiterals(writer: JsonWriter, private val forceQuoting: Boolean) : Composer(writer) { +internal class ComposerForUnquotedLiterals(writer: InternalJsonWriter, private val forceQuoting: Boolean) : Composer(writer) { override fun printQuoted(value: String) { if (forceQuoting) super.printQuoted(value) else super.print(value) } } internal class ComposerWithPrettyPrint( - writer: JsonWriter, + writer: InternalJsonWriter, private val json: Json ) : Composer(writer) { private var level = 0 diff --git a/formats/json/commonMain/src/kotlinx/serialization/json/internal/JsonElementMarker.kt b/formats/json/commonMain/src/kotlinx/serialization/json/internal/JsonElementMarker.kt index 2535739c..85a4624b 100644 --- a/formats/json/commonMain/src/kotlinx/serialization/json/internal/JsonElementMarker.kt +++ b/formats/json/commonMain/src/kotlinx/serialization/json/internal/JsonElementMarker.kt @@ -2,7 +2,6 @@ * Copyright 2017-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. */ -@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER") package kotlinx.serialization.json.internal diff --git a/formats/json/commonMain/src/kotlinx/serialization/json/internal/JsonStreams.kt b/formats/json/commonMain/src/kotlinx/serialization/json/internal/JsonStreams.kt index 74dbe45d..05f025ce 100644 --- a/formats/json/commonMain/src/kotlinx/serialization/json/internal/JsonStreams.kt +++ b/formats/json/commonMain/src/kotlinx/serialization/json/internal/JsonStreams.kt @@ -4,38 +4,42 @@ import kotlinx.serialization.* import kotlinx.serialization.json.DecodeSequenceMode import kotlinx.serialization.json.Json -@PublishedApi -internal interface JsonWriter { - fun writeLong(value: Long) - fun writeChar(char: Char) - fun write(text: String) - fun writeQuoted(text: String) - fun release() +@RequiresOptIn(level = RequiresOptIn.Level.ERROR) +internal annotation class JsonFriendModuleApi + +@JsonFriendModuleApi +public interface InternalJsonWriter { + public fun writeLong(value: Long) + public fun writeChar(char: Char) + public fun write(text: String) + public fun writeQuoted(text: String) + public fun release() } -@PublishedApi -internal interface SerialReader { - fun read(buffer: CharArray, bufferOffset: Int, count: Int): Int +@JsonFriendModuleApi +public interface InternalJsonReader { + public fun read(buffer: CharArray, bufferOffset: Int, count: Int): Int } -@PublishedApi -internal fun <T> Json.encodeByWriter(writer: JsonWriter, serializer: SerializationStrategy<T>, value: T) { +@JsonFriendModuleApi +public fun <T> encodeByWriter(json: Json, writer: InternalJsonWriter, serializer: SerializationStrategy<T>, value: T) { val encoder = StreamingJsonEncoder( - writer, this, + writer, json, WriteMode.OBJ, - arrayOfNulls(WriteMode.values().size) + arrayOfNulls(WriteMode.entries.size) ) encoder.encodeSerializableValue(serializer, value) } -@PublishedApi -internal fun <T> Json.decodeByReader( +@JsonFriendModuleApi +public fun <T> decodeByReader( + json: Json, deserializer: DeserializationStrategy<T>, - reader: SerialReader + reader: InternalJsonReader ): T { val lexer = ReaderJsonLexer(reader) try { - val input = StreamingJsonDecoder(this, WriteMode.OBJ, lexer, deserializer.descriptor, null) + val input = StreamingJsonDecoder(json, WriteMode.OBJ, lexer, deserializer.descriptor, null) val result = input.decodeSerializableValue(deserializer) lexer.expectEof() return result @@ -44,21 +48,23 @@ internal fun <T> Json.decodeByReader( } } -@PublishedApi +@JsonFriendModuleApi @ExperimentalSerializationApi -internal fun <T> Json.decodeToSequenceByReader( - reader: SerialReader, +public fun <T> decodeToSequenceByReader( + json: Json, + reader: InternalJsonReader, deserializer: DeserializationStrategy<T>, format: DecodeSequenceMode = DecodeSequenceMode.AUTO_DETECT ): Sequence<T> { val lexer = ReaderJsonLexer(reader, CharArray(BATCH_SIZE)) // Unpooled buffer due to lazy nature of sequence - val iter = JsonIterator(format, this, lexer, deserializer) + val iter = JsonIterator(format, json, lexer, deserializer) return Sequence { iter }.constrainOnce() } -@PublishedApi +@JsonFriendModuleApi @ExperimentalSerializationApi -internal inline fun <reified T> Json.decodeToSequenceByReader( - reader: SerialReader, +public inline fun <reified T> decodeToSequenceByReader( + json: Json, + reader: InternalJsonReader, format: DecodeSequenceMode = DecodeSequenceMode.AUTO_DETECT -): Sequence<T> = decodeToSequenceByReader(reader, serializersModule.serializer(), format) +): Sequence<T> = decodeToSequenceByReader(json, reader, json.serializersModule.serializer(), format) diff --git a/formats/json/commonMain/src/kotlinx/serialization/json/internal/JsonToStringWriter.kt b/formats/json/commonMain/src/kotlinx/serialization/json/internal/JsonToStringWriter.kt index 4df35def..a6a123cc 100644 --- a/formats/json/commonMain/src/kotlinx/serialization/json/internal/JsonToStringWriter.kt +++ b/formats/json/commonMain/src/kotlinx/serialization/json/internal/JsonToStringWriter.kt @@ -1,6 +1,6 @@ package kotlinx.serialization.json.internal -internal expect class JsonToStringWriter constructor() : JsonWriter { +internal expect class JsonToStringWriter constructor() : InternalJsonWriter { override fun writeChar(char: Char) override fun writeLong(value: Long) override fun write(text: String) diff --git a/formats/json/commonMain/src/kotlinx/serialization/json/internal/StreamingJsonDecoder.kt b/formats/json/commonMain/src/kotlinx/serialization/json/internal/StreamingJsonDecoder.kt index ce930090..4e373f1f 100644 --- a/formats/json/commonMain/src/kotlinx/serialization/json/internal/StreamingJsonDecoder.kt +++ b/formats/json/commonMain/src/kotlinx/serialization/json/internal/StreamingJsonDecoder.kt @@ -49,7 +49,6 @@ internal open class StreamingJsonDecoder( override fun decodeJsonElement(): JsonElement = JsonTreeReader(json.configuration, lexer).read() - @Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") override fun <T> decodeSerializableValue(deserializer: DeserializationStrategy<T>): T { try { /* @@ -350,13 +349,14 @@ internal open class StreamingJsonDecoder( } } -@InternalSerializationApi -public fun <T> Json.decodeStringToJsonTree( +@JsonFriendModuleApi // used in json-tests +public fun <T> decodeStringToJsonTree( + json: Json, deserializer: DeserializationStrategy<T>, source: String ): JsonElement { val lexer = StringJsonLexer(source) - val input = StreamingJsonDecoder(this, WriteMode.OBJ, lexer, deserializer.descriptor, null) + val input = StreamingJsonDecoder(json, WriteMode.OBJ, lexer, deserializer.descriptor, null) val tree = input.decodeJsonElement() lexer.expectEof() return tree diff --git a/formats/json/commonMain/src/kotlinx/serialization/json/internal/StreamingJsonEncoder.kt b/formats/json/commonMain/src/kotlinx/serialization/json/internal/StreamingJsonEncoder.kt index c6f76cb3..4f7b1ec7 100644 --- a/formats/json/commonMain/src/kotlinx/serialization/json/internal/StreamingJsonEncoder.kt +++ b/formats/json/commonMain/src/kotlinx/serialization/json/internal/StreamingJsonEncoder.kt @@ -10,7 +10,6 @@ import kotlinx.serialization.descriptors.* import kotlinx.serialization.encoding.* import kotlinx.serialization.json.* import kotlinx.serialization.modules.* -import kotlin.native.concurrent.* private val unsignedNumberDescriptors = setOf( UInt.serializer().descriptor, @@ -34,7 +33,7 @@ internal class StreamingJsonEncoder( ) : JsonEncoder, AbstractEncoder() { internal constructor( - output: JsonWriter, json: Json, mode: WriteMode, + output: InternalJsonWriter, json: Json, mode: WriteMode, modeReuseCache: Array<JsonEncoder?> ) : this(Composer(output, json), json, mode, modeReuseCache) @@ -164,7 +163,7 @@ internal class StreamingJsonEncoder( else -> super.encodeInline(descriptor) } - private inline fun <reified T: Composer> composerAs(composerCreator: (writer: JsonWriter, forceQuoting: Boolean) -> T): T { + private inline fun <reified T: Composer> composerAs(composerCreator: (writer: InternalJsonWriter, forceQuoting: Boolean) -> T): T { // If we're inside encodeInline().encodeSerializableValue, we should preserve the forceQuoting state // inside the composer, but not in the encoder (otherwise we'll get into `if (forceQuoting) encodeString(value.toString())` part // and unsigned numbers would be encoded incorrectly) diff --git a/formats/json/commonMain/src/kotlinx/serialization/json/internal/StringOps.kt b/formats/json/commonMain/src/kotlinx/serialization/json/internal/StringOps.kt index f488d903..ed76ba04 100644 --- a/formats/json/commonMain/src/kotlinx/serialization/json/internal/StringOps.kt +++ b/formats/json/commonMain/src/kotlinx/serialization/json/internal/StringOps.kt @@ -12,7 +12,6 @@ private fun toHexChar(i: Int) : Char { else (d - 10 + 'a'.code).toChar() } -@PublishedApi internal val ESCAPE_STRINGS: Array<String?> = arrayOfNulls<String>(93).apply { for (c in 0..0x1f) { val c1 = toHexChar(c shr 12) @@ -68,4 +67,4 @@ internal fun String.toBooleanStrictOrNull(): Boolean? = when { this.equals("true", ignoreCase = true) -> true this.equals("false", ignoreCase = true) -> false else -> null -}
\ No newline at end of file +} diff --git a/formats/json/commonMain/src/kotlinx/serialization/json/internal/TreeJsonDecoder.kt b/formats/json/commonMain/src/kotlinx/serialization/json/internal/TreeJsonDecoder.kt index 4b355f65..aedfb95f 100644 --- a/formats/json/commonMain/src/kotlinx/serialization/json/internal/TreeJsonDecoder.kt +++ b/formats/json/commonMain/src/kotlinx/serialization/json/internal/TreeJsonDecoder.kt @@ -15,12 +15,12 @@ import kotlinx.serialization.json.* import kotlinx.serialization.modules.* import kotlin.jvm.* -@InternalSerializationApi -public fun <T> Json.readJson(element: JsonElement, deserializer: DeserializationStrategy<T>): T { +@JsonFriendModuleApi +public fun <T> readJson(json: Json, element: JsonElement, deserializer: DeserializationStrategy<T>): T { val input = when (element) { - is JsonObject -> JsonTreeDecoder(this, element) - is JsonArray -> JsonTreeListDecoder(this, element) - is JsonLiteral, JsonNull -> JsonPrimitiveDecoder(this, element as JsonPrimitive) + is JsonObject -> JsonTreeDecoder(json, element) + is JsonArray -> JsonTreeListDecoder(json, element) + is JsonLiteral, JsonNull -> JsonPrimitiveDecoder(json, element as JsonPrimitive) } return input.decodeSerializableValue(deserializer) } diff --git a/formats/json/commonMain/src/kotlinx/serialization/json/internal/TreeJsonEncoder.kt b/formats/json/commonMain/src/kotlinx/serialization/json/internal/TreeJsonEncoder.kt index e42d4250..5e3c8086 100644 --- a/formats/json/commonMain/src/kotlinx/serialization/json/internal/TreeJsonEncoder.kt +++ b/formats/json/commonMain/src/kotlinx/serialization/json/internal/TreeJsonEncoder.kt @@ -14,10 +14,10 @@ import kotlinx.serialization.modules.* import kotlin.collections.set import kotlin.jvm.* -@InternalSerializationApi -public fun <T> Json.writeJson(value: T, serializer: SerializationStrategy<T>): JsonElement { +@JsonFriendModuleApi +public fun <T> writeJson(json: Json, value: T, serializer: SerializationStrategy<T>): JsonElement { lateinit var result: JsonElement - val encoder = JsonTreeEncoder(this) { result = it } + val encoder = JsonTreeEncoder(json) { result = it } encoder.encodeSerializableValue(serializer, value) return result } diff --git a/formats/json/commonMain/src/kotlinx/serialization/json/internal/lexer/ReaderJsonLexer.kt b/formats/json/commonMain/src/kotlinx/serialization/json/internal/lexer/ReaderJsonLexer.kt index 3c785f86..24e5b472 100644 --- a/formats/json/commonMain/src/kotlinx/serialization/json/internal/lexer/ReaderJsonLexer.kt +++ b/formats/json/commonMain/src/kotlinx/serialization/json/internal/lexer/ReaderJsonLexer.kt @@ -2,8 +2,6 @@ * Copyright 2017-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. */ -@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER") - package kotlinx.serialization.json.internal internal const val BATCH_SIZE: Int = 16 * 1024 @@ -13,7 +11,7 @@ private const val DEFAULT_THRESHOLD = 128 * For some reason this hand-rolled implementation is faster than * fun ArrayAsSequence(s: CharArray): CharSequence = java.nio.CharBuffer.wrap(s, 0, length) */ -internal class ArrayAsSequence(private val buffer: CharArray) : CharSequence { +internal class ArrayAsSequence(internal val buffer: CharArray) : CharSequence { override var length: Int = buffer.size override fun get(index: Int): Char = buffer[index] @@ -35,7 +33,7 @@ internal class ArrayAsSequence(private val buffer: CharArray) : CharSequence { } internal class ReaderJsonLexer( - private val reader: SerialReader, + private val reader: InternalJsonReader, private val buffer: CharArray = CharArrayPoolBatchSize.take() ) : AbstractJsonLexer() { private var threshold: Int = DEFAULT_THRESHOLD // chars diff --git a/formats/json/jsWasmMain/src/kotlinx/serialization/json/internal/JsonToStringWriterJsWasm.kt b/formats/json/jsWasmMain/src/kotlinx/serialization/json/internal/JsonToStringWriterJsWasm.kt index 806a1d84..387ed7e9 100644 --- a/formats/json/jsWasmMain/src/kotlinx/serialization/json/internal/JsonToStringWriterJsWasm.kt +++ b/formats/json/jsWasmMain/src/kotlinx/serialization/json/internal/JsonToStringWriterJsWasm.kt @@ -1,6 +1,6 @@ package kotlinx.serialization.json.internal -internal actual open class JsonToStringWriter actual constructor(): JsonWriter { +internal actual open class JsonToStringWriter actual constructor(): InternalJsonWriter { private val sb = StringBuilder(128) actual override fun writeLong(value: Long) { diff --git a/formats/json/jvmMain/src/kotlinx/serialization/json/JvmStreams.kt b/formats/json/jvmMain/src/kotlinx/serialization/json/JvmStreams.kt index 4af10453..329e309d 100644 --- a/formats/json/jvmMain/src/kotlinx/serialization/json/JvmStreams.kt +++ b/formats/json/jvmMain/src/kotlinx/serialization/json/JvmStreams.kt @@ -22,7 +22,7 @@ public fun <T> Json.encodeToStream( ) { val writer = JsonToJavaStreamWriter(stream) try { - encodeByWriter(writer, serializer, value) + encodeByWriter(this, writer, serializer, value) } finally { writer.release() } @@ -58,7 +58,7 @@ public fun <T> Json.decodeFromStream( ): T { val reader = JavaStreamSerialReader(stream) try { - return decodeByReader(deserializer, reader) + return decodeByReader(this, deserializer, reader) } finally { reader.release() } @@ -102,7 +102,7 @@ public fun <T> Json.decodeToSequence( deserializer: DeserializationStrategy<T>, format: DecodeSequenceMode = DecodeSequenceMode.AUTO_DETECT ): Sequence<T> { - return decodeToSequenceByReader(JavaStreamSerialReader(stream), deserializer, format) + return decodeToSequenceByReader(this, JavaStreamSerialReader(stream), deserializer, format) } /** diff --git a/formats/json/jvmMain/src/kotlinx/serialization/json/internal/JsonToStringWriter.kt b/formats/json/jvmMain/src/kotlinx/serialization/json/internal/JsonToStringWriter.kt index e11c21c1..56667248 100644 --- a/formats/json/jvmMain/src/kotlinx/serialization/json/internal/JsonToStringWriter.kt +++ b/formats/json/jvmMain/src/kotlinx/serialization/json/internal/JsonToStringWriter.kt @@ -25,7 +25,7 @@ package kotlinx.serialization.json.internal * 3) We pool char arrays in order to save excess resizes, allocations * and nulls-out of arrays. */ -internal actual class JsonToStringWriter : JsonWriter { +internal actual class JsonToStringWriter : InternalJsonWriter { private var array: CharArray = CharArrayPool.take() private var size = 0 diff --git a/formats/json/jvmMain/src/kotlinx/serialization/json/internal/JvmJsonStreams.kt b/formats/json/jvmMain/src/kotlinx/serialization/json/internal/JvmJsonStreams.kt index 274dd4dc..e8e0d9a5 100644 --- a/formats/json/jvmMain/src/kotlinx/serialization/json/internal/JvmJsonStreams.kt +++ b/formats/json/jvmMain/src/kotlinx/serialization/json/internal/JvmJsonStreams.kt @@ -3,7 +3,7 @@ package kotlinx.serialization.json.internal import java.io.InputStream import java.io.OutputStream -internal class JsonToJavaStreamWriter(private val stream: OutputStream) : JsonWriter { +internal class JsonToJavaStreamWriter(private val stream: OutputStream) : InternalJsonWriter { private val buffer = ByteArrayPool.take() private var charArray = CharArrayPool.take() private var indexInBuffer: Int = 0 @@ -253,7 +253,7 @@ internal class JsonToJavaStreamWriter(private val stream: OutputStream) : JsonWr } } -internal class JavaStreamSerialReader(stream: InputStream) : SerialReader { +internal class JavaStreamSerialReader(stream: InputStream) : InternalJsonReader { // NB: not closed on purpose, it is the responsibility of the caller private val reader = CharsetReader(stream, Charsets.UTF_8) diff --git a/formats/json/nativeMain/src/kotlinx/serialization/json/internal/JsonToStringWriter.kt b/formats/json/nativeMain/src/kotlinx/serialization/json/internal/JsonToStringWriter.kt index d996fc33..137f3bc7 100644 --- a/formats/json/nativeMain/src/kotlinx/serialization/json/internal/JsonToStringWriter.kt +++ b/formats/json/nativeMain/src/kotlinx/serialization/json/internal/JsonToStringWriter.kt @@ -1,6 +1,6 @@ package kotlinx.serialization.json.internal -internal actual open class JsonToStringWriter actual constructor(): JsonWriter { +internal actual open class JsonToStringWriter actual constructor(): InternalJsonWriter { private val sb = StringBuilder(128) actual override fun writeLong(value: Long) { diff --git a/formats/protobuf/build.gradle b/formats/protobuf/build.gradle index c2183b28..9f93b18f 100644 --- a/formats/protobuf/build.gradle +++ b/formats/protobuf/build.gradle @@ -21,8 +21,11 @@ clean { } kotlin { - sourceSets { + configureEach { + languageSettings.optIn("kotlinx.serialization.internal.CoreFriendModuleApi") + } + commonMain { dependencies { api project(":kotlinx-serialization-core") diff --git a/formats/protobuf/commonMain/src/kotlinx/serialization/protobuf/internal/ProtobufDecoding.kt b/formats/protobuf/commonMain/src/kotlinx/serialization/protobuf/internal/ProtobufDecoding.kt index d2a28b5c..861e2bf3 100644 --- a/formats/protobuf/commonMain/src/kotlinx/serialization/protobuf/internal/ProtobufDecoding.kt +++ b/formats/protobuf/commonMain/src/kotlinx/serialization/protobuf/internal/ProtobufDecoding.kt @@ -3,7 +3,7 @@ */ @file:OptIn(ExperimentalSerializationApi::class) -@file:Suppress("UNCHECKED_CAST", "INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +@file:Suppress("UNCHECKED_CAST") package kotlinx.serialization.protobuf.internal @@ -213,7 +213,7 @@ internal open class ProtobufDecoder( val mapEntrySerial = kotlinx.serialization.builtins.MapEntrySerializer(serializer.keySerializer, serializer.valueSerializer) val oldSet = (previousValue as? Map<Any?, Any?>)?.entries - val setOfEntries = LinkedHashSetSerializer(mapEntrySerial).merge(this, oldSet) + val setOfEntries = (SetSerializer(mapEntrySerial) as AbstractCollectionSerializer<Map.Entry<Any?, Any?>, Set<Map.Entry<Any?, Any?>>, *>).merge(this, oldSet) return setOfEntries.associateBy({ it.key }, { it.value }) as T } |