Skip to content

Commit 7b75e39

Browse files
authored
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
1 parent 7d287c8 commit 7b75e39

File tree

30 files changed

+152
-112
lines changed

30 files changed

+152
-112
lines changed

buildSrc/src/main/kotlin/Java9Modularity.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ object Java9Modularity {
131131
// To support LV override when set in aggregate builds
132132
languageVersion = compileTask.kotlinOptions.languageVersion
133133
freeCompilerArgs += listOf("-Xjdk-release=9", "-Xsuppress-version-warnings")
134+
options.optIn.addAll(compileTask.kotlinOptions.options.optIn)
134135
}
135136
// work-around for https://youtrack.jetbrains.com/issue/KT-60583
136137
inputs.files(

core/commonMain/src/kotlinx/serialization/internal/ElementMarker.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44

55
package kotlinx.serialization.internal
66

7-
import kotlinx.serialization.ExperimentalSerializationApi
7+
import kotlinx.serialization.*
88
import kotlinx.serialization.descriptors.SerialDescriptor
99
import kotlinx.serialization.encoding.CompositeDecoder
1010

1111
@OptIn(ExperimentalSerializationApi::class)
12-
@PublishedApi
13-
internal class ElementMarker(
12+
@CoreFriendModuleApi
13+
public class ElementMarker(
1414
private val descriptor: SerialDescriptor,
1515
// Instead of inheritance and virtual function in order to keep cross-module internal modifier via suppresses
1616
// Can be reworked via public + internal api if necessary
@@ -45,15 +45,15 @@ internal class ElementMarker(
4545
}
4646
}
4747

48-
fun mark(index: Int) {
48+
public fun mark(index: Int) {
4949
if (index < Long.SIZE_BITS) {
5050
lowerMarks = lowerMarks or (1L shl index)
5151
} else {
5252
markHigh(index)
5353
}
5454
}
5555

56-
fun nextUnmarkedIndex(): Int {
56+
public fun nextUnmarkedIndex(): Int {
5757
val elementsCount = descriptor.elementsCount
5858
while (lowerMarks != -1L) {
5959
val index = lowerMarks.inv().countTrailingZeroBits()
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
package kotlinx.serialization.internal
22

3-
import kotlinx.serialization.*
43
import kotlinx.serialization.descriptors.*
54

65
/*
7-
* Methods that are required for kotlinx-serialization-json, but are not effectively public
8-
* and actually represent our own technical debt.
9-
* This methods are not intended for public use
6+
* Methods that are required for kotlinx-serialization-json, but are not effectively public.
7+
*
8+
* Anything marker with this annotation is not intended for public use.
109
*/
10+
@RequiresOptIn(level = RequiresOptIn.Level.ERROR)
11+
internal annotation class CoreFriendModuleApi
1112

12-
@InternalSerializationApi
13-
@Deprecated(message = "Should not be used", level = DeprecationLevel.ERROR)
13+
@CoreFriendModuleApi
1414
public fun SerialDescriptor.jsonCachedSerialNames(): Set<String> = cachedSerialNames()

core/commonTest/src/kotlinx/serialization/ElementMarkerTest.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ package kotlinx.serialization
22

33
import kotlinx.serialization.descriptors.*
44
import kotlinx.serialization.encoding.CompositeDecoder
5-
import kotlinx.serialization.internal.ElementMarker
5+
import kotlinx.serialization.internal.*
66
import kotlin.test.Test
77
import kotlin.test.assertEquals
88

9+
@OptIn(CoreFriendModuleApi::class)
910
class ElementMarkerTest {
1011
@Test
1112
fun testNothingWasRead() {

formats/json-okio/build.gradle.kts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ apply(from = rootProject.file("gradle/configure-source-sets.gradle"))
1515

1616
kotlin {
1717
sourceSets {
18+
configureEach {
19+
languageSettings {
20+
optIn("kotlinx.serialization.internal.CoreFriendModuleApi")
21+
optIn("kotlinx.serialization.json.internal.JsonFriendModuleApi")
22+
}
23+
}
1824
val commonMain by getting {
1925
dependencies {
2026
api(project(":kotlinx-serialization-core"))
@@ -58,4 +64,4 @@ if (isNewWasmTargetEnabled) {
5864
}
5965
}
6066
}
61-
}
67+
}

formats/json-okio/commonMain/src/kotlinx/serialization/json/okio/OkioStreams.kt

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
* Copyright 2017-2022 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
33
*/
44

5-
@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
6-
75
package kotlinx.serialization.json.okio
86

97
import kotlinx.serialization.*
@@ -29,7 +27,7 @@ public fun <T> Json.encodeToBufferedSink(
2927
) {
3028
val writer = JsonToOkioStreamWriter(sink)
3129
try {
32-
encodeByWriter(writer, serializer, value)
30+
encodeByWriter(this, writer, serializer, value)
3331
} finally {
3432
writer.release()
3533
}
@@ -62,7 +60,7 @@ public fun <T> Json.decodeFromBufferedSource(
6260
deserializer: DeserializationStrategy<T>,
6361
source: BufferedSource
6462
): T {
65-
return decodeByReader(deserializer, OkioSerialReader(source))
63+
return decodeByReader(this, deserializer, OkioSerialReader(source))
6664
}
6765

6866
/**
@@ -101,7 +99,7 @@ public fun <T> Json.decodeBufferedSourceToSequence(
10199
deserializer: DeserializationStrategy<T>,
102100
format: DecodeSequenceMode = DecodeSequenceMode.AUTO_DETECT
103101
): Sequence<T> {
104-
return decodeToSequenceByReader(OkioSerialReader(source), deserializer, format)
102+
return decodeToSequenceByReader(this, OkioSerialReader(source), deserializer, format)
105103
}
106104

107105
/**

formats/json-okio/commonMain/src/kotlinx/serialization/json/okio/internal/OkioJsonStreams.kt

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,39 @@
22
* Copyright 2017-2022 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
33
*/
44

5-
@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER", "CANNOT_OVERRIDE_INVISIBLE_MEMBER")
6-
75
package kotlinx.serialization.json.okio.internal
86

9-
import kotlinx.serialization.json.internal.ESCAPE_STRINGS
10-
import kotlinx.serialization.json.internal.JsonWriter
11-
import kotlinx.serialization.json.internal.SerialReader
7+
import kotlinx.serialization.json.internal.*
128
import okio.*
139

14-
internal class JsonToOkioStreamWriter(private val sink: BufferedSink) : JsonWriter {
10+
// Copied from kotlinx/serialization/json/internal/StringOps.kt
11+
private fun toHexChar(i: Int) : Char {
12+
val d = i and 0xf
13+
return if (d < 10) (d + '0'.code).toChar()
14+
else (d - 10 + 'a'.code).toChar()
15+
}
16+
17+
// Copied from kotlinx/serialization/json/internal/StringOps.kt
18+
private val ESCAPE_STRINGS: Array<String?> = arrayOfNulls<String>(93).apply {
19+
for (c in 0..0x1f) {
20+
val c1 = toHexChar(c shr 12)
21+
val c2 = toHexChar(c shr 8)
22+
val c3 = toHexChar(c shr 4)
23+
val c4 = toHexChar(c)
24+
this[c] = "\\u$c1$c2$c3$c4"
25+
}
26+
this['"'.code] = "\\\""
27+
this['\\'.code] = "\\\\"
28+
this['\t'.code] = "\\t"
29+
this['\b'.code] = "\\b"
30+
this['\n'.code] = "\\n"
31+
this['\r'.code] = "\\r"
32+
this[0x0c] = "\\f"
33+
}
34+
35+
36+
37+
internal class JsonToOkioStreamWriter(private val sink: BufferedSink) : InternalJsonWriter {
1538
override fun writeLong(value: Long) {
1639
write(value.toString())
1740
}
@@ -54,7 +77,7 @@ private const val HIGH_SURROGATE_HEADER = 0xd800 - (0x010000 ushr 10)
5477
private const val LOW_SURROGATE_HEADER = 0xdc00
5578

5679

57-
internal class OkioSerialReader(private val source: BufferedSource): SerialReader {
80+
internal class OkioSerialReader(private val source: BufferedSource): InternalJsonReader {
5881
/*
5982
A sequence of code points is read from UTF-8, some of it can take 2 characters.
6083
In case the last code point requires 2 characters, and the array is already full, we buffer the second character

formats/json-tests/build.gradle.kts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ tasks.named("koverVerify") {
2525

2626
kotlin {
2727
sourceSets {
28+
configureEach {
29+
languageSettings {
30+
optIn("kotlinx.serialization.internal.CoreFriendModuleApi")
31+
optIn("kotlinx.serialization.json.internal.JsonFriendModuleApi")
32+
}
33+
}
2834
val commonTest by getting {
2935
dependencies {
3036
api(project(":kotlinx-serialization-json"))
@@ -64,4 +70,4 @@ if (!isNewWasmTargetEnabled) {
6470
tasks.named("wasmD8Test", KotlinJsTest::class) {
6571
filter.excludePatterns += "kotlinx.serialization.features.EmojiTest"
6672
}
67-
}
73+
}

formats/json-tests/commonTest/src/kotlinx/serialization/json/JsonTestBase.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ abstract class JsonTestBase {
4949
encodeViaStream(serializer, value)
5050
}
5151
JsonTestingMode.TREE -> {
52-
val tree = writeJson(value, serializer)
52+
val tree = writeJson(this, value, serializer)
5353
encodeToString(tree)
5454
}
5555
JsonTestingMode.OKIO_STREAMS -> {
@@ -77,8 +77,8 @@ abstract class JsonTestBase {
7777
decodeViaStream(deserializer, source)
7878
}
7979
JsonTestingMode.TREE -> {
80-
val tree = decodeStringToJsonTree(deserializer, source)
81-
readJson(tree, deserializer)
80+
val tree = decodeStringToJsonTree(this, deserializer, source)
81+
readJson(this, tree, deserializer)
8282
}
8383
JsonTestingMode.OKIO_STREAMS -> {
8484
val buffer = Buffer()

formats/json/api/kotlinx-serialization-json.api

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -383,33 +383,29 @@ public final class kotlinx/serialization/json/JvmStreamsKt {
383383
public static final fun encodeToStream (Lkotlinx/serialization/json/Json;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Ljava/io/OutputStream;)V
384384
}
385385

386-
public final class kotlinx/serialization/json/internal/JsonStreamsKt {
387-
public static final fun decodeByReader (Lkotlinx/serialization/json/Json;Lkotlinx/serialization/DeserializationStrategy;Lkotlinx/serialization/json/internal/SerialReader;)Ljava/lang/Object;
388-
public static final fun decodeToSequenceByReader (Lkotlinx/serialization/json/Json;Lkotlinx/serialization/json/internal/SerialReader;Lkotlinx/serialization/DeserializationStrategy;Lkotlinx/serialization/json/DecodeSequenceMode;)Lkotlin/sequences/Sequence;
389-
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;
390-
public static final fun encodeByWriter (Lkotlinx/serialization/json/Json;Lkotlinx/serialization/json/internal/JsonWriter;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V
386+
public abstract interface class kotlinx/serialization/json/internal/InternalJsonReader {
387+
public abstract fun read ([CII)I
391388
}
392389

393-
public abstract interface class kotlinx/serialization/json/internal/JsonWriter {
390+
public abstract interface class kotlinx/serialization/json/internal/InternalJsonWriter {
394391
public abstract fun release ()V
395392
public abstract fun write (Ljava/lang/String;)V
396393
public abstract fun writeChar (C)V
397394
public abstract fun writeLong (J)V
398395
public abstract fun writeQuoted (Ljava/lang/String;)V
399396
}
400397

401-
public abstract interface class kotlinx/serialization/json/internal/SerialReader {
402-
public abstract fun read ([CII)I
398+
public final class kotlinx/serialization/json/internal/JsonStreamsKt {
399+
public static final fun decodeByReader (Lkotlinx/serialization/json/Json;Lkotlinx/serialization/DeserializationStrategy;Lkotlinx/serialization/json/internal/InternalJsonReader;)Ljava/lang/Object;
400+
public static final fun decodeToSequenceByReader (Lkotlinx/serialization/json/Json;Lkotlinx/serialization/json/internal/InternalJsonReader;Lkotlinx/serialization/DeserializationStrategy;Lkotlinx/serialization/json/DecodeSequenceMode;)Lkotlin/sequences/Sequence;
401+
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;
402+
public static final fun encodeByWriter (Lkotlinx/serialization/json/Json;Lkotlinx/serialization/json/internal/InternalJsonWriter;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V
403403
}
404404

405405
public final class kotlinx/serialization/json/internal/StreamingJsonDecoderKt {
406406
public static final fun decodeStringToJsonTree (Lkotlinx/serialization/json/Json;Lkotlinx/serialization/DeserializationStrategy;Ljava/lang/String;)Lkotlinx/serialization/json/JsonElement;
407407
}
408408

409-
public final class kotlinx/serialization/json/internal/StringOpsKt {
410-
public static final fun getESCAPE_STRINGS ()[Ljava/lang/String;
411-
}
412-
413409
public final class kotlinx/serialization/json/internal/TreeJsonDecoderKt {
414410
public static final fun readJson (Lkotlinx/serialization/json/Json;Lkotlinx/serialization/json/JsonElement;Lkotlinx/serialization/DeserializationStrategy;)Ljava/lang/Object;
415411
}

0 commit comments

Comments
 (0)