mirror of
https://github.com/fankes/moshi.git
synced 2025-10-18 23:49:21 +08:00
Update to Kotlin 1.5 (and associated deps) (#1339)
This commit is contained in:
@@ -14,12 +14,20 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm")
|
kotlin("jvm")
|
||||||
id("com.vanniktech.maven.publish")
|
id("com.vanniktech.maven.publish")
|
||||||
id("ru.vyarus.animalsniffer")
|
id("ru.vyarus.animalsniffer")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.withType<KotlinCompile>().configureEach {
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = "1.6"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly(Dependencies.jsr305)
|
compileOnly(Dependencies.jsr305)
|
||||||
api(project(":moshi"))
|
api(project(":moshi"))
|
||||||
|
@@ -31,8 +31,8 @@ buildscript {
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("com.vanniktech.maven.publish") version "0.14.2" apply false
|
id("com.vanniktech.maven.publish") version "0.14.2" apply false
|
||||||
id("org.jetbrains.dokka") version "1.4.30" apply false
|
id("org.jetbrains.dokka") version "1.4.32" apply false
|
||||||
id("com.diffplug.spotless") version "5.11.0"
|
id("com.diffplug.spotless") version "5.12.4"
|
||||||
id("ru.vyarus.animalsniffer") version "1.5.3" apply false
|
id("ru.vyarus.animalsniffer") version "1.5.3" apply false
|
||||||
id("me.champeau.gradle.japicmp") version "0.2.9" apply false
|
id("me.champeau.gradle.japicmp") version "0.2.9" apply false
|
||||||
}
|
}
|
||||||
|
@@ -18,7 +18,7 @@ object Dependencies {
|
|||||||
|
|
||||||
const val asm = "org.ow2.asm:asm:7.1"
|
const val asm = "org.ow2.asm:asm:7.1"
|
||||||
const val jsr305 = "com.google.code.findbugs:jsr305:3.0.2"
|
const val jsr305 = "com.google.code.findbugs:jsr305:3.0.2"
|
||||||
const val ktlintVersion = "0.39.0"
|
const val ktlintVersion = "0.41.0"
|
||||||
const val okio = "com.squareup.okio:okio:2.10.0"
|
const val okio = "com.squareup.okio:okio:2.10.0"
|
||||||
|
|
||||||
object AnimalSniffer {
|
object AnimalSniffer {
|
||||||
@@ -39,8 +39,8 @@ object Dependencies {
|
|||||||
}
|
}
|
||||||
|
|
||||||
object Kotlin {
|
object Kotlin {
|
||||||
const val version = "1.4.32"
|
const val version = "1.5.0"
|
||||||
const val metadata = "org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.2.0"
|
const val metadata = "org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.3.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
object KotlinPoet {
|
object KotlinPoet {
|
||||||
@@ -53,7 +53,7 @@ object Dependencies {
|
|||||||
|
|
||||||
object Testing {
|
object Testing {
|
||||||
const val assertj = "org.assertj:assertj-core:3.11.1"
|
const val assertj = "org.assertj:assertj-core:3.11.1"
|
||||||
const val compileTesting = "com.github.tschuchortdev:kotlin-compile-testing:1.3.6"
|
const val compileTesting = "com.github.tschuchortdev:kotlin-compile-testing:1.4.0"
|
||||||
const val junit = "junit:junit:4.13.2"
|
const val junit = "junit:junit:4.13.2"
|
||||||
const val truth = "com.google.truth:truth:1.0.1"
|
const val truth = "com.google.truth:truth:1.0.1"
|
||||||
}
|
}
|
||||||
|
@@ -22,7 +22,7 @@ plugins {
|
|||||||
kotlin("jvm")
|
kotlin("jvm")
|
||||||
kotlin("kapt")
|
kotlin("kapt")
|
||||||
id("com.vanniktech.maven.publish")
|
id("com.vanniktech.maven.publish")
|
||||||
id("com.github.johnrengelman.shadow") version "6.0.0"
|
id("com.github.johnrengelman.shadow") version "7.0.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<KotlinCompile>().configureEach {
|
tasks.withType<KotlinCompile>().configureEach {
|
||||||
@@ -102,6 +102,6 @@ val shadowJar = tasks.shadowJar.apply {
|
|||||||
}
|
}
|
||||||
|
|
||||||
artifacts {
|
artifacts {
|
||||||
runtime(shadowJar)
|
runtimeOnly(shadowJar)
|
||||||
archives(shadowJar)
|
archives(shadowJar)
|
||||||
}
|
}
|
||||||
|
@@ -31,6 +31,7 @@ import com.squareup.kotlinpoet.asClassName
|
|||||||
import com.squareup.kotlinpoet.asTypeName
|
import com.squareup.kotlinpoet.asTypeName
|
||||||
import com.squareup.moshi.JsonAdapter
|
import com.squareup.moshi.JsonAdapter
|
||||||
import com.squareup.moshi.Types
|
import com.squareup.moshi.Types
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
/** A JsonAdapter that can be used to encode and decode a particular field. */
|
/** A JsonAdapter that can be used to encode and decode a particular field. */
|
||||||
internal data class DelegateKey(
|
internal data class DelegateKey(
|
||||||
@@ -50,7 +51,7 @@ internal data class DelegateKey(
|
|||||||
"At${it.typeName.rawType().simpleName}"
|
"At${it.typeName.rawType().simpleName}"
|
||||||
}
|
}
|
||||||
val adapterName = nameAllocator.newName(
|
val adapterName = nameAllocator.newName(
|
||||||
"${type.toVariableName().decapitalize()}${qualifierNames}Adapter",
|
"${type.toVariableName().replaceFirstChar { it.lowercase(Locale.US) }}${qualifierNames}Adapter",
|
||||||
this
|
this
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -188,111 +188,111 @@ internal class KotlinJsonAdapter<T>(
|
|||||||
public class KotlinJsonAdapterFactory : JsonAdapter.Factory {
|
public class KotlinJsonAdapterFactory : JsonAdapter.Factory {
|
||||||
override fun create(type: Type, annotations: MutableSet<out Annotation>, moshi: Moshi):
|
override fun create(type: Type, annotations: MutableSet<out Annotation>, moshi: Moshi):
|
||||||
JsonAdapter<*>? {
|
JsonAdapter<*>? {
|
||||||
if (annotations.isNotEmpty()) return null
|
if (annotations.isNotEmpty()) return null
|
||||||
|
|
||||||
val rawType = type.rawType
|
val rawType = type.rawType
|
||||||
if (rawType.isInterface) return null
|
if (rawType.isInterface) return null
|
||||||
if (rawType.isEnum) return null
|
if (rawType.isEnum) return null
|
||||||
if (!rawType.isAnnotationPresent(KOTLIN_METADATA)) return null
|
if (!rawType.isAnnotationPresent(KOTLIN_METADATA)) return null
|
||||||
if (Util.isPlatformType(rawType)) return null
|
if (Util.isPlatformType(rawType)) return null
|
||||||
try {
|
try {
|
||||||
val generatedAdapter = generatedAdapter(moshi, type, rawType)
|
val generatedAdapter = generatedAdapter(moshi, type, rawType)
|
||||||
if (generatedAdapter != null) {
|
if (generatedAdapter != null) {
|
||||||
return generatedAdapter
|
return generatedAdapter
|
||||||
}
|
|
||||||
} catch (e: RuntimeException) {
|
|
||||||
if (e.cause !is ClassNotFoundException) {
|
|
||||||
throw e
|
|
||||||
}
|
|
||||||
// Fall back to a reflective adapter when the generated adapter is not found.
|
|
||||||
}
|
}
|
||||||
|
} catch (e: RuntimeException) {
|
||||||
require(!rawType.isLocalClass) {
|
if (e.cause !is ClassNotFoundException) {
|
||||||
"Cannot serialize local class or object expression ${rawType.name}"
|
throw e
|
||||||
}
|
}
|
||||||
val rawTypeKotlin = rawType.kotlin
|
// Fall back to a reflective adapter when the generated adapter is not found.
|
||||||
require(!rawTypeKotlin.isAbstract) {
|
|
||||||
"Cannot serialize abstract class ${rawType.name}"
|
|
||||||
}
|
|
||||||
require(!rawTypeKotlin.isInner) {
|
|
||||||
"Cannot serialize inner class ${rawType.name}"
|
|
||||||
}
|
|
||||||
require(rawTypeKotlin.objectInstance == null) {
|
|
||||||
"Cannot serialize object declaration ${rawType.name}"
|
|
||||||
}
|
|
||||||
require(!rawTypeKotlin.isSealed) {
|
|
||||||
"Cannot reflectively serialize sealed class ${rawType.name}. Please register an adapter."
|
|
||||||
}
|
|
||||||
|
|
||||||
val constructor = rawTypeKotlin.primaryConstructor ?: return null
|
|
||||||
val parametersByName = constructor.parameters.associateBy { it.name }
|
|
||||||
constructor.isAccessible = true
|
|
||||||
|
|
||||||
val bindingsByName = LinkedHashMap<String, KotlinJsonAdapter.Binding<Any, Any?>>()
|
|
||||||
|
|
||||||
for (property in rawTypeKotlin.memberProperties) {
|
|
||||||
val parameter = parametersByName[property.name]
|
|
||||||
|
|
||||||
if (Modifier.isTransient(property.javaField?.modifiers ?: 0)) {
|
|
||||||
require(parameter == null || parameter.isOptional) {
|
|
||||||
"No default value for transient constructor $parameter"
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
require(parameter == null || parameter.type == property.returnType) {
|
|
||||||
"'${property.name}' has a constructor parameter of type ${parameter!!.type} but a property of type ${property.returnType}."
|
|
||||||
}
|
|
||||||
|
|
||||||
if (property !is KMutableProperty1 && parameter == null) continue
|
|
||||||
|
|
||||||
property.isAccessible = true
|
|
||||||
val allAnnotations = property.annotations.toMutableList()
|
|
||||||
var jsonAnnotation = property.findAnnotation<Json>()
|
|
||||||
|
|
||||||
if (parameter != null) {
|
|
||||||
allAnnotations += parameter.annotations
|
|
||||||
if (jsonAnnotation == null) {
|
|
||||||
jsonAnnotation = parameter.findAnnotation()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val name = jsonAnnotation?.name ?: property.name
|
|
||||||
val resolvedPropertyType = resolve(type, rawType, property.returnType.javaType)
|
|
||||||
val adapter = moshi.adapter<Any>(
|
|
||||||
resolvedPropertyType,
|
|
||||||
Util.jsonAnnotations(allAnnotations.toTypedArray()),
|
|
||||||
property.name
|
|
||||||
)
|
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
bindingsByName[property.name] = KotlinJsonAdapter.Binding(
|
|
||||||
name,
|
|
||||||
jsonAnnotation?.name ?: name,
|
|
||||||
adapter,
|
|
||||||
property as KProperty1<Any, Any?>,
|
|
||||||
parameter,
|
|
||||||
parameter?.index ?: -1
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
val bindings = ArrayList<KotlinJsonAdapter.Binding<Any, Any?>?>()
|
|
||||||
|
|
||||||
for (parameter in constructor.parameters) {
|
|
||||||
val binding = bindingsByName.remove(parameter.name)
|
|
||||||
require(binding != null || parameter.isOptional) {
|
|
||||||
"No property for required constructor $parameter"
|
|
||||||
}
|
|
||||||
bindings += binding
|
|
||||||
}
|
|
||||||
|
|
||||||
var index = bindings.size
|
|
||||||
for (bindingByName in bindingsByName) {
|
|
||||||
bindings += bindingByName.value.copy(propertyIndex = index++)
|
|
||||||
}
|
|
||||||
|
|
||||||
val nonTransientBindings = bindings.filterNotNull()
|
|
||||||
val options = JsonReader.Options.of(*nonTransientBindings.map { it.name }.toTypedArray())
|
|
||||||
return KotlinJsonAdapter(constructor, bindings, nonTransientBindings, options).nullSafe()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
require(!rawType.isLocalClass) {
|
||||||
|
"Cannot serialize local class or object expression ${rawType.name}"
|
||||||
|
}
|
||||||
|
val rawTypeKotlin = rawType.kotlin
|
||||||
|
require(!rawTypeKotlin.isAbstract) {
|
||||||
|
"Cannot serialize abstract class ${rawType.name}"
|
||||||
|
}
|
||||||
|
require(!rawTypeKotlin.isInner) {
|
||||||
|
"Cannot serialize inner class ${rawType.name}"
|
||||||
|
}
|
||||||
|
require(rawTypeKotlin.objectInstance == null) {
|
||||||
|
"Cannot serialize object declaration ${rawType.name}"
|
||||||
|
}
|
||||||
|
require(!rawTypeKotlin.isSealed) {
|
||||||
|
"Cannot reflectively serialize sealed class ${rawType.name}. Please register an adapter."
|
||||||
|
}
|
||||||
|
|
||||||
|
val constructor = rawTypeKotlin.primaryConstructor ?: return null
|
||||||
|
val parametersByName = constructor.parameters.associateBy { it.name }
|
||||||
|
constructor.isAccessible = true
|
||||||
|
|
||||||
|
val bindingsByName = LinkedHashMap<String, KotlinJsonAdapter.Binding<Any, Any?>>()
|
||||||
|
|
||||||
|
for (property in rawTypeKotlin.memberProperties) {
|
||||||
|
val parameter = parametersByName[property.name]
|
||||||
|
|
||||||
|
if (Modifier.isTransient(property.javaField?.modifiers ?: 0)) {
|
||||||
|
require(parameter == null || parameter.isOptional) {
|
||||||
|
"No default value for transient constructor $parameter"
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
require(parameter == null || parameter.type == property.returnType) {
|
||||||
|
"'${property.name}' has a constructor parameter of type ${parameter!!.type} but a property of type ${property.returnType}."
|
||||||
|
}
|
||||||
|
|
||||||
|
if (property !is KMutableProperty1 && parameter == null) continue
|
||||||
|
|
||||||
|
property.isAccessible = true
|
||||||
|
val allAnnotations = property.annotations.toMutableList()
|
||||||
|
var jsonAnnotation = property.findAnnotation<Json>()
|
||||||
|
|
||||||
|
if (parameter != null) {
|
||||||
|
allAnnotations += parameter.annotations
|
||||||
|
if (jsonAnnotation == null) {
|
||||||
|
jsonAnnotation = parameter.findAnnotation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val name = jsonAnnotation?.name ?: property.name
|
||||||
|
val resolvedPropertyType = resolve(type, rawType, property.returnType.javaType)
|
||||||
|
val adapter = moshi.adapter<Any>(
|
||||||
|
resolvedPropertyType,
|
||||||
|
Util.jsonAnnotations(allAnnotations.toTypedArray()),
|
||||||
|
property.name
|
||||||
|
)
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
bindingsByName[property.name] = KotlinJsonAdapter.Binding(
|
||||||
|
name,
|
||||||
|
jsonAnnotation?.name ?: name,
|
||||||
|
adapter,
|
||||||
|
property as KProperty1<Any, Any?>,
|
||||||
|
parameter,
|
||||||
|
parameter?.index ?: -1
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val bindings = ArrayList<KotlinJsonAdapter.Binding<Any, Any?>?>()
|
||||||
|
|
||||||
|
for (parameter in constructor.parameters) {
|
||||||
|
val binding = bindingsByName.remove(parameter.name)
|
||||||
|
require(binding != null || parameter.isOptional) {
|
||||||
|
"No property for required constructor $parameter"
|
||||||
|
}
|
||||||
|
bindings += binding
|
||||||
|
}
|
||||||
|
|
||||||
|
var index = bindings.size
|
||||||
|
for (bindingByName in bindingsByName) {
|
||||||
|
bindings += bindingByName.value.copy(propertyIndex = index++)
|
||||||
|
}
|
||||||
|
|
||||||
|
val nonTransientBindings = bindings.filterNotNull()
|
||||||
|
val options = JsonReader.Options.of(*nonTransientBindings.map { it.name }.toTypedArray())
|
||||||
|
return KotlinJsonAdapter(constructor, bindings, nonTransientBindings, options).nullSafe()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -26,8 +26,7 @@ tasks.withType<KotlinCompile>().configureEach {
|
|||||||
@Suppress("SuspiciousCollectionReassignment")
|
@Suppress("SuspiciousCollectionReassignment")
|
||||||
freeCompilerArgs += listOf(
|
freeCompilerArgs += listOf(
|
||||||
"-Werror",
|
"-Werror",
|
||||||
"-Xopt-in=kotlin.ExperimentalStdlibApi",
|
"-Xopt-in=kotlin.ExperimentalStdlibApi"
|
||||||
"-Xinline-classes"
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -285,9 +285,9 @@ class DualKotlinTest(useReflection: Boolean) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test fun inlineClass() {
|
@Test fun inlineClass() {
|
||||||
val adapter = moshi.adapter<InlineClass>()
|
val adapter = moshi.adapter<ValueClass>()
|
||||||
|
|
||||||
val inline = InlineClass(5)
|
val inline = ValueClass(5)
|
||||||
|
|
||||||
val expectedJson =
|
val expectedJson =
|
||||||
"""{"i":5}"""
|
"""{"i":5}"""
|
||||||
@@ -300,12 +300,12 @@ class DualKotlinTest(useReflection: Boolean) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
data class InlineConsumer(val inline: InlineClass)
|
data class InlineConsumer(val inline: ValueClass)
|
||||||
|
|
||||||
@Test fun inlineClassConsumer() {
|
@Test fun inlineClassConsumer() {
|
||||||
val adapter = moshi.adapter<InlineConsumer>()
|
val adapter = moshi.adapter<InlineConsumer>()
|
||||||
|
|
||||||
val consumer = InlineConsumer(InlineClass(23))
|
val consumer = InlineConsumer(ValueClass(23))
|
||||||
|
|
||||||
@Language("JSON")
|
@Language("JSON")
|
||||||
val expectedJson =
|
val expectedJson =
|
||||||
@@ -622,9 +622,10 @@ typealias GenericTypeAlias = List<out GenericClass<in TypeAlias>?>?
|
|||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
data class GenericClass<T>(val value: T)
|
data class GenericClass<T>(val value: T)
|
||||||
|
|
||||||
// Has to be outside since inline classes are only allowed on top level
|
// Has to be outside since value classes are only allowed on top level
|
||||||
|
@JvmInline
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
inline class InlineClass(val i: Int)
|
value class ValueClass(val i: Int)
|
||||||
|
|
||||||
typealias A = Int
|
typealias A = Int
|
||||||
typealias NullableA = A?
|
typealias NullableA = A?
|
||||||
|
@@ -1191,11 +1191,14 @@ class GeneratedAdaptersTest {
|
|||||||
annotation class Uppercase(val inFrench: Boolean, val onSundays: Boolean = false)
|
annotation class Uppercase(val inFrench: Boolean, val onSundays: Boolean = false)
|
||||||
|
|
||||||
class UppercaseJsonAdapter {
|
class UppercaseJsonAdapter {
|
||||||
@ToJson fun toJson(@Uppercase(inFrench = true) s: String): String {
|
@ToJson
|
||||||
return s.toUpperCase(Locale.US)
|
fun toJson(@Uppercase(inFrench = true) s: String): String {
|
||||||
|
return s.uppercase(Locale.US)
|
||||||
}
|
}
|
||||||
@FromJson @Uppercase(inFrench = true) fun fromJson(s: String): String {
|
@FromJson
|
||||||
return s.toLowerCase(Locale.US)
|
@Uppercase(inFrench = true)
|
||||||
|
fun fromJson(s: String): String {
|
||||||
|
return s.lowercase(Locale.US)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -24,10 +24,13 @@ import java.util.Locale
|
|||||||
annotation class UppercaseInAnnotationPackage
|
annotation class UppercaseInAnnotationPackage
|
||||||
|
|
||||||
class UppercaseInAnnotationPackageJsonAdapter {
|
class UppercaseInAnnotationPackageJsonAdapter {
|
||||||
@ToJson fun toJson(@UppercaseInAnnotationPackage s: String): String {
|
@ToJson
|
||||||
return s.toUpperCase(Locale.US)
|
fun toJson(@UppercaseInAnnotationPackage s: String): String {
|
||||||
|
return s.uppercase(Locale.US)
|
||||||
}
|
}
|
||||||
@FromJson @UppercaseInAnnotationPackage fun fromJson(s: String): String {
|
@FromJson
|
||||||
return s.toLowerCase(Locale.US)
|
@UppercaseInAnnotationPackage
|
||||||
|
fun fromJson(s: String): String {
|
||||||
|
return s.lowercase(Locale.US)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -916,11 +916,14 @@ class KotlinJsonAdapterTest {
|
|||||||
annotation class Uppercase
|
annotation class Uppercase
|
||||||
|
|
||||||
class UppercaseJsonAdapter {
|
class UppercaseJsonAdapter {
|
||||||
@ToJson fun toJson(@Uppercase s: String): String {
|
@ToJson
|
||||||
return s.toUpperCase(Locale.US)
|
fun toJson(@Uppercase s: String): String {
|
||||||
|
return s.uppercase(Locale.US)
|
||||||
}
|
}
|
||||||
@FromJson @Uppercase fun fromJson(s: String): String {
|
@FromJson
|
||||||
return s.toLowerCase(Locale.US)
|
@Uppercase
|
||||||
|
fun fromJson(s: String): String {
|
||||||
|
return s.lowercase(Locale.US)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -23,11 +23,14 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<KotlinCompile>()
|
tasks.withType<KotlinCompile>()
|
||||||
.matching { it.name.contains("test", true) }
|
|
||||||
.configureEach {
|
.configureEach {
|
||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
@Suppress("SuspiciousCollectionReassignment") // It's not suspicious
|
jvmTarget = "1.6"
|
||||||
freeCompilerArgs += listOf("-Xopt-in=kotlin.ExperimentalStdlibApi")
|
|
||||||
|
if (name.contains("test", true)) {
|
||||||
|
@Suppress("SuspiciousCollectionReassignment") // It's not suspicious
|
||||||
|
freeCompilerArgs += listOf("-Xopt-in=kotlin.ExperimentalStdlibApi")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user