mirror of
https://github.com/fankes/moshi.git
synced 2025-10-20 00:19:21 +08:00
Switch to spotless and format code (#1196)
* Add spotless configuration * Reformat! * Add copyright config for build.gradle.kts files * Add toeholds for headers
This commit is contained in:
@@ -18,8 +18,8 @@ package com.squareup.moshi
|
||||
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
|
||||
|
||||
@Deprecated(
|
||||
message = "this moved to avoid a package name conflict in the Java Platform Module System.",
|
||||
replaceWith = ReplaceWith("com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory")
|
||||
message = "this moved to avoid a package name conflict in the Java Platform Module System.",
|
||||
replaceWith = ReplaceWith("com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory")
|
||||
)
|
||||
class KotlinJsonAdapterFactory
|
||||
: JsonAdapter.Factory by KotlinJsonAdapterFactory()
|
||||
class KotlinJsonAdapterFactory :
|
||||
JsonAdapter.Factory by KotlinJsonAdapterFactory()
|
||||
|
@@ -28,7 +28,6 @@ import com.squareup.moshi.internal.Util.resolve
|
||||
import java.lang.reflect.Modifier
|
||||
import java.lang.reflect.Type
|
||||
import java.util.AbstractMap.SimpleEntry
|
||||
import kotlin.collections.Map.Entry
|
||||
import kotlin.reflect.KFunction
|
||||
import kotlin.reflect.KMutableProperty1
|
||||
import kotlin.reflect.KParameter
|
||||
@@ -78,16 +77,17 @@ internal class KotlinJsonAdapter<T>(
|
||||
val propertyIndex = binding.propertyIndex
|
||||
if (values[propertyIndex] !== ABSENT_VALUE) {
|
||||
throw JsonDataException(
|
||||
"Multiple values for '${binding.property.name}' at ${reader.path}")
|
||||
"Multiple values for '${binding.property.name}' at ${reader.path}"
|
||||
)
|
||||
}
|
||||
|
||||
values[propertyIndex] = binding.adapter.fromJson(reader)
|
||||
|
||||
if (values[propertyIndex] == null && !binding.property.returnType.isMarkedNullable) {
|
||||
throw Util.unexpectedNull(
|
||||
binding.property.name,
|
||||
binding.jsonName,
|
||||
reader
|
||||
binding.property.name,
|
||||
binding.jsonName,
|
||||
reader
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -98,9 +98,9 @@ internal class KotlinJsonAdapter<T>(
|
||||
if (values[i] === ABSENT_VALUE && !constructor.parameters[i].isOptional) {
|
||||
if (!constructor.parameters[i].type.isMarkedNullable) {
|
||||
throw Util.missingProperty(
|
||||
constructor.parameters[i].name,
|
||||
allBindings[i]?.jsonName,
|
||||
reader
|
||||
constructor.parameters[i].name,
|
||||
allBindings[i]?.jsonName,
|
||||
reader
|
||||
)
|
||||
}
|
||||
values[i] = null // Replace absent with null.
|
||||
@@ -154,8 +154,8 @@ internal class KotlinJsonAdapter<T>(
|
||||
|
||||
/** A simple [Map] that uses parameter indexes instead of sorting or hashing. */
|
||||
class IndexedParameterMap(
|
||||
private val parameterKeys: List<KParameter>,
|
||||
private val parameterValues: Array<Any?>
|
||||
private val parameterKeys: List<KParameter>,
|
||||
private val parameterValues: Array<Any?>
|
||||
) : AbstractMutableMap<KParameter, Any?>() {
|
||||
|
||||
override fun put(key: KParameter, value: Any?): Any? = null
|
||||
@@ -180,110 +180,113 @@ internal class KotlinJsonAdapter<T>(
|
||||
}
|
||||
|
||||
class KotlinJsonAdapterFactory : JsonAdapter.Factory {
|
||||
override fun create(type: Type, annotations: MutableSet<out Annotation>, moshi: Moshi)
|
||||
: JsonAdapter<*>? {
|
||||
if (annotations.isNotEmpty()) return null
|
||||
override fun create(type: Type, annotations: MutableSet<out Annotation>, moshi: Moshi):
|
||||
JsonAdapter<*>? {
|
||||
if (annotations.isNotEmpty()) 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 (Util.isPlatformType(rawType)) return null
|
||||
try {
|
||||
val generatedAdapter = generatedAdapter(moshi, type, rawType)
|
||||
if (generatedAdapter != null) {
|
||||
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.
|
||||
}
|
||||
|
||||
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"
|
||||
val rawType = Types.getRawType(type)
|
||||
if (rawType.isInterface) return null
|
||||
if (rawType.isEnum) return null
|
||||
if (!rawType.isAnnotationPresent(KOTLIN_METADATA)) return null
|
||||
if (Util.isPlatformType(rawType)) return null
|
||||
try {
|
||||
val generatedAdapter = generatedAdapter(moshi, type, rawType)
|
||||
if (generatedAdapter != null) {
|
||||
return generatedAdapter
|
||||
}
|
||||
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()
|
||||
} catch (e: RuntimeException) {
|
||||
if (e.cause !is ClassNotFoundException) {
|
||||
throw e
|
||||
}
|
||||
// Fall back to a reflective adapter when the generated adapter is not found.
|
||||
}
|
||||
|
||||
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)
|
||||
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."
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
bindingsByName[property.name] = KotlinJsonAdapter.Binding(
|
||||
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 bindings = ArrayList<KotlinJsonAdapter.Binding<Any, Any?>?>()
|
||||
|
||||
val nonTransientBindings = bindings.filterNotNull()
|
||||
val options = JsonReader.Options.of(*nonTransientBindings.map { it.name }.toTypedArray())
|
||||
return KotlinJsonAdapter(constructor, bindings, nonTransientBindings, options).nullSafe()
|
||||
}
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
@@ -12,11 +12,11 @@ class KotlinJsonAdapterTest {
|
||||
@Test
|
||||
fun fallsBackToReflectiveAdapterWithoutCodegen() {
|
||||
val moshi = Moshi.Builder()
|
||||
.add(KotlinJsonAdapterFactory())
|
||||
.build()
|
||||
.add(KotlinJsonAdapterFactory())
|
||||
.build()
|
||||
val adapter = moshi.adapter(Data::class.java)
|
||||
assertThat(adapter.toString()).isEqualTo(
|
||||
"KotlinJsonAdapter(com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterTest.Data).nullSafe()"
|
||||
"KotlinJsonAdapter(com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterTest.Data).nullSafe()"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user