Disallow irregular Kotlin classes. (#424)
This commit is contained in:
parent
9deeb62e77
commit
5b194964a9
2 changed files with 105 additions and 6 deletions
|
@ -162,17 +162,32 @@ class KotlinJsonAdapterFactory : JsonAdapter.Factory {
|
|||
if (!annotations.isEmpty()) return null
|
||||
|
||||
val rawType = Types.getRawType(type)
|
||||
if (rawType.isInterface) return null
|
||||
if (rawType.isEnum) return null
|
||||
if (!rawType.isAnnotationPresent(KOTLIN_METADATA)) return null
|
||||
if (ClassJsonAdapter.isPlatformType(rawType)) return null
|
||||
|
||||
val constructor = rawType.kotlin.primaryConstructor ?: return null
|
||||
if (rawType.isLocalClass) {
|
||||
throw IllegalArgumentException("Cannot serialize local class or object expression ${rawType.name}")
|
||||
}
|
||||
val rawTypeKotlin = rawType.kotlin
|
||||
if (rawTypeKotlin.isAbstract) {
|
||||
throw IllegalArgumentException("Cannot serialize abstract class ${rawType.name}")
|
||||
}
|
||||
if (rawTypeKotlin.isInner) {
|
||||
throw IllegalArgumentException("Cannot serialize inner class ${rawType.name}")
|
||||
}
|
||||
if (rawTypeKotlin.objectInstance != null) {
|
||||
throw IllegalArgumentException("Cannot serialize object declaration ${rawType.name}")
|
||||
}
|
||||
|
||||
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 rawType.kotlin.memberProperties) {
|
||||
for (property in rawTypeKotlin.memberProperties) {
|
||||
val parameter = parametersByName[property.name]
|
||||
|
||||
if (Modifier.isTransient(property.javaField?.modifiers ?: 0)) {
|
||||
|
|
|
@ -134,9 +134,8 @@ class KotlinJsonAdapterTest {
|
|||
class RequiredValueAbsent(var a: Int = 3, var b: Int)
|
||||
|
||||
@Test fun nonNullConstructorParameterCalledWithNullFailsWithJsonDataException() {
|
||||
class Data(val a: String)
|
||||
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
|
||||
val jsonAdapter = moshi.adapter(Data::class.java)
|
||||
val jsonAdapter = moshi.adapter(HasNonNullConstructorParameter::class.java)
|
||||
|
||||
try {
|
||||
jsonAdapter.fromJson("{\"a\":null}")
|
||||
|
@ -146,10 +145,11 @@ class KotlinJsonAdapterTest {
|
|||
}
|
||||
}
|
||||
|
||||
class HasNonNullConstructorParameter(val a: String)
|
||||
|
||||
@Test fun nonNullPropertySetToNullFailsWithJsonDataException() {
|
||||
class Data { var a: String = "" }
|
||||
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
|
||||
val jsonAdapter = moshi.adapter(Data::class.java)
|
||||
val jsonAdapter = moshi.adapter(HasNonNullProperty::class.java)
|
||||
|
||||
try {
|
||||
jsonAdapter.fromJson("{\"a\":null}")
|
||||
|
@ -159,6 +159,10 @@ class KotlinJsonAdapterTest {
|
|||
}
|
||||
}
|
||||
|
||||
class HasNonNullProperty {
|
||||
var a: String = ""
|
||||
}
|
||||
|
||||
@Test fun duplicatedValue() {
|
||||
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
|
||||
val jsonAdapter = moshi.adapter(DuplicateValue::class.java)
|
||||
|
@ -576,6 +580,86 @@ class KotlinJsonAdapterTest {
|
|||
A, B
|
||||
}
|
||||
|
||||
@Test fun interfacesNotSupported() {
|
||||
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
|
||||
try {
|
||||
moshi.adapter(Interface::class.java)
|
||||
fail()
|
||||
} catch (e: IllegalArgumentException) {
|
||||
assertThat(e).hasMessage("No JsonAdapter for interface " +
|
||||
"com.squareup.moshi.KotlinJsonAdapterTest\$Interface annotated []")
|
||||
}
|
||||
}
|
||||
|
||||
interface Interface
|
||||
|
||||
@Test fun abstractClassesNotSupported() {
|
||||
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
|
||||
try {
|
||||
moshi.adapter(AbstractClass::class.java)
|
||||
fail()
|
||||
} catch (e: IllegalArgumentException) {
|
||||
assertThat(e).hasMessage(
|
||||
"Cannot serialize abstract class com.squareup.moshi.KotlinJsonAdapterTest\$AbstractClass")
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AbstractClass(val a: Int)
|
||||
|
||||
@Test fun innerClassesNotSupported() {
|
||||
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
|
||||
try {
|
||||
moshi.adapter(InnerClass::class.java)
|
||||
fail()
|
||||
} catch (e: IllegalArgumentException) {
|
||||
assertThat(e).hasMessage(
|
||||
"Cannot serialize inner class com.squareup.moshi.KotlinJsonAdapterTest\$InnerClass")
|
||||
}
|
||||
}
|
||||
|
||||
inner class InnerClass(val a: Int)
|
||||
|
||||
@Test fun localClassesNotSupported() {
|
||||
class LocalClass(val a: Int)
|
||||
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
|
||||
try {
|
||||
moshi.adapter(LocalClass::class.java)
|
||||
fail()
|
||||
} catch (e: IllegalArgumentException) {
|
||||
assertThat(e).hasMessage("Cannot serialize local class or object expression " +
|
||||
"com.squareup.moshi.KotlinJsonAdapterTest\$localClassesNotSupported\$LocalClass")
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun objectDeclarationsNotSupported() {
|
||||
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
|
||||
try {
|
||||
moshi.adapter(ObjectDeclaration.javaClass)
|
||||
fail()
|
||||
} catch (e: IllegalArgumentException) {
|
||||
assertThat(e).hasMessage("Cannot serialize object declaration " +
|
||||
"com.squareup.moshi.KotlinJsonAdapterTest\$ObjectDeclaration")
|
||||
}
|
||||
}
|
||||
|
||||
object ObjectDeclaration {
|
||||
var a = 5
|
||||
}
|
||||
|
||||
@Test fun objectExpressionsNotSupported() {
|
||||
val expression = object : Any() {
|
||||
var a = 5
|
||||
}
|
||||
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
|
||||
try {
|
||||
moshi.adapter(expression.javaClass)
|
||||
fail()
|
||||
} catch (e: IllegalArgumentException) {
|
||||
assertThat(e).hasMessage("Cannot serialize local class or object expression " +
|
||||
"com.squareup.moshi.KotlinJsonAdapterTest\$objectExpressionsNotSupported\$expression$1")
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun manyProperties32() {
|
||||
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
|
||||
val jsonAdapter = moshi.adapter(ManyProperties32::class.java)
|
||||
|
|
Loading…
Reference in a new issue