Small cleanups from a few past PRs (#1509)

This commit is contained in:
Zac Sweers
2022-01-20 10:23:22 -05:00
committed by GitHub
parent c5be69a93c
commit c5e98e5be8
4 changed files with 65 additions and 53 deletions

View File

@@ -95,7 +95,7 @@ internal class AdapterMethodsFactory(
}
companion object {
fun get(adapter: Any): AdapterMethodsFactory {
operator fun invoke(adapter: Any): AdapterMethodsFactory {
val toAdapters = mutableListOf<AdapterMethod>()
val fromAdapters = mutableListOf<AdapterMethod>()
@@ -132,7 +132,7 @@ internal class AdapterMethodsFactory(
* Returns an object that calls a `method` method on `adapter` in service of
* converting an object to JSON.
*/
fun toAdapter(adapter: Any, method: Method): AdapterMethod {
private fun toAdapter(adapter: Any, method: Method): AdapterMethod {
method.isAccessible = true
val returnType = method.genericReturnType
val parameterTypes = method.genericParameterTypes
@@ -142,10 +142,11 @@ internal class AdapterMethodsFactory(
returnType == Void.TYPE &&
parametersAreJsonAdapters(2, parameterTypes)
return when {
// void pointToJson(JsonWriter jsonWriter, Point point) {
// void pointToJson(JsonWriter jsonWriter, Point point, JsonAdapter<?> adapter, ...) {
methodSignatureIncludesJsonWriterAndJsonAdapter -> {
// void pointToJson(JsonWriter jsonWriter, Point point) {
// void pointToJson(JsonWriter jsonWriter, Point point, JsonAdapter<?> adapter, ...) {
val qualifierAnnotations = parameterAnnotations[1].jsonAnnotations
object : AdapterMethod(
adaptersOffset = 2,
type = parameterTypes[1],
@@ -156,7 +157,7 @@ internal class AdapterMethodsFactory(
nullable = true
) {
override fun toJson(moshi: Moshi, writer: JsonWriter, value: Any?) {
invoke(writer, value)
invokeMethod(writer, value)
}
}
}
@@ -174,10 +175,14 @@ internal class AdapterMethodsFactory(
method = method,
nullable = nullable
) {
private lateinit var delegate: JsonAdapter<Any>
override fun bind(moshi: Moshi, factory: JsonAdapter.Factory) {
super.bind(moshi, factory)
delegate = if (Types.equals(parameterTypes[0], returnType) && qualifierAnnotations == returnTypeAnnotations) {
val shouldSkip = Types.equals(parameterTypes[0], returnType) &&
qualifierAnnotations == returnTypeAnnotations
delegate = if (shouldSkip) {
moshi.nextAdapter(factory, returnType, returnTypeAnnotations)
} else {
moshi.adapter(returnType, returnTypeAnnotations)
@@ -185,19 +190,20 @@ internal class AdapterMethodsFactory(
}
override fun toJson(moshi: Moshi, writer: JsonWriter, value: Any?) {
val intermediate = invoke(value)
delegate.toJson(writer, intermediate)
delegate.toJson(writer, invokeMethod(value))
}
}
}
else -> {
throw IllegalArgumentException(
"""Unexpected signature for $method.
@ToJson method signatures may have one of the following structures:
<any access modifier> void toJson(JsonWriter writer, T value) throws <any>;
<any access modifier> void toJson(JsonWriter writer, T value, JsonAdapter<any> delegate, <any more delegates>) throws <any>;
<any access modifier> R toJson(T value) throws <any>;
"""
"""
Unexpected signature for $method.
@ToJson method signatures may have one of the following structures:
<any access modifier> void toJson(JsonWriter writer, T value) throws <any>;
<any access modifier> void toJson(JsonWriter writer, T value, JsonAdapter<any> delegate, <any more delegates>) throws <any>;
<any access modifier> R toJson(T value) throws <any>;
""".trimIndent()
)
}
}
@@ -217,7 +223,7 @@ internal class AdapterMethodsFactory(
* Returns an object that calls a `method` method on `adapter` in service of
* converting an object from JSON.
*/
fun fromAdapter(adapter: Any, method: Method): AdapterMethod {
private fun fromAdapter(adapter: Any, method: Method): AdapterMethod {
method.isAccessible = true
val returnType = method.genericReturnType
val returnTypeAnnotations = method.jsonAnnotations
@@ -240,7 +246,7 @@ internal class AdapterMethodsFactory(
method = method,
nullable = true
) {
override fun fromJson(moshi: Moshi, reader: JsonReader) = invoke(reader)
override fun fromJson(moshi: Moshi, reader: JsonReader) = invokeMethod(reader)
}
}
parameterTypes.size == 1 && returnType != Void.TYPE -> {
@@ -269,18 +275,20 @@ internal class AdapterMethodsFactory(
override fun fromJson(moshi: Moshi, reader: JsonReader): Any? {
val intermediate = delegate.fromJson(reader)
return invoke(intermediate)
return invokeMethod(intermediate)
}
}
}
else -> {
throw IllegalArgumentException(
"""Unexpected signature for $method.
@FromJson method signatures may have one of the following structures:
<any access modifier> R fromJson(JsonReader jsonReader) throws <any>;
<any access modifier> R fromJson(JsonReader jsonReader, JsonAdapter<any> delegate, <any more delegates>) throws <any>;
<any access modifier> R fromJson(T value) throws <any>;
"""
"""
Unexpected signature for $method.
@FromJson method signatures may have one of the following structures:
<any access modifier> R fromJson(JsonReader jsonReader) throws <any>;
<any access modifier> R fromJson(JsonReader jsonReader, JsonAdapter<any> delegate, <any more delegates>) throws <any>;
<any access modifier> R fromJson(T value) throws <any>;
""".trimIndent()
)
}
}
@@ -322,9 +330,7 @@ internal class AdapterMethodsFactory(
val jsonAnnotations = parameterAnnotations[i].jsonAnnotations
jsonAdapters[i - adaptersOffset] =
if (Types.equals(this.type, type) && annotations == jsonAnnotations) {
moshi.nextAdapter(
factory, type, jsonAnnotations
)
moshi.nextAdapter(factory, type, jsonAnnotations)
} else {
moshi.adapter<Any>(type, jsonAnnotations)
}
@@ -337,9 +343,9 @@ internal class AdapterMethodsFactory(
open fun fromJson(moshi: Moshi, reader: JsonReader): Any? = throw AssertionError()
/** Invoke the method with one fixed argument, plus any number of JSON adapter arguments. */
protected fun invoke(initialFixedArgumentForAdapterMethod: Any?): Any? {
protected fun invokeMethod(arg: Any?): Any? {
val args = arrayOfNulls<Any>(1 + jsonAdapters.size)
args[0] = initialFixedArgumentForAdapterMethod
args[0] = arg
jsonAdapters.copyInto(args, 1, 0, jsonAdapters.size)
return try {
@@ -350,10 +356,10 @@ internal class AdapterMethodsFactory(
}
/** Invoke the method with two fixed arguments, plus any number of JSON adapter arguments. */
protected fun invoke(fixedArgument1: Any?, fixedArgument2: Any?): Any? {
protected fun invokeMethod(arg0: Any?, arg1: Any?): Any? {
val args = arrayOfNulls<Any>(2 + jsonAdapters.size)
args[0] = fixedArgument1
args[1] = fixedArgument2
args[0] = arg0
args[1] = arg1
jsonAdapters.copyInto(args, 2, 0, jsonAdapters.size)
return try {

View File

@@ -39,7 +39,6 @@ import java.lang.reflect.Type
*
* Fields from platform classes are omitted from both serialization and deserialization unless they
* are either public or protected. This includes the following packages and their subpackages:
*
* * `android.*`
* * `androidx.*`
* * `java.*`
@@ -47,7 +46,6 @@ import java.lang.reflect.Type
* * `kotlin.*`
* * `kotlinx.*`
* * `scala.*`
*
*/
internal class ClassJsonAdapter<T>(
private val classFactory: ClassFactory<T>,
@@ -103,12 +101,12 @@ internal class ClassJsonAdapter<T>(
internal class FieldBinding<T>(val name: String, val field: Field, val adapter: JsonAdapter<T>) {
fun read(reader: JsonReader, value: Any?) {
val fieldValue = adapter.fromJson(reader)
field[value] = fieldValue
field.set(value, fieldValue)
}
@Suppress("UNCHECKED_CAST") // We require that field's values are of type T.
fun write(writer: JsonWriter, value: Any?) {
val fieldValue = field[value] as T
val fieldValue = field.get(value) as T
adapter.toJson(writer, fieldValue)
}
}
@@ -145,19 +143,24 @@ internal class ClassJsonAdapter<T>(
require(!rawType.isAnonymousClass) {
"Cannot serialize anonymous class ${rawType.name}"
}
require(!rawType.isLocalClass) {
"Cannot serialize local class ${rawType.name}"
}
val isNonStaticNestedClass = rawType.enclosingClass != null && !isStatic(rawType.modifiers)
require(!isNonStaticNestedClass) {
"Cannot serialize non-static nested class ${rawType.name}"
}
require(!isAbstract(rawType.modifiers)) {
"Cannot serialize abstract class ${rawType.name}"
}
require(!rawType.isKotlin) {
"Cannot serialize Kotlin type ${rawType.name}. Reflective serialization of Kotlin classes without using kotlin-reflect has undefined and unexpected behavior. Please use KotlinJsonAdapterFactory from the moshi-kotlin artifact or use code gen from the moshi-kotlin-codegen artifact."
}
val classFactory = ClassFactory.get<Any>(rawType)
val fields = sortedMapOf<String, FieldBinding<*>>()
var parentType = type
@@ -216,8 +219,11 @@ internal class ClassJsonAdapter<T>(
/** Returns true if fields with `modifiers` are included in the emitted JSON. */
private fun includeField(platformType: Boolean, modifiers: Int): Boolean {
if (isStatic(modifiers) || isTransient(modifiers)) return false
return isPublic(modifiers) || isProtected(modifiers) || !platformType
return if (isStatic(modifiers) || isTransient(modifiers)) {
false
} else {
isPublic(modifiers) || isProtected(modifiers) || !platformType
}
}
}
}

View File

@@ -213,7 +213,7 @@ public class Moshi internal constructor(builder: Builder) {
}
public fun add(adapter: Any): Builder = apply {
add(AdapterMethodsFactory.get(adapter))
add(AdapterMethodsFactory(adapter))
}
@Suppress("unused")
@@ -236,7 +236,7 @@ public class Moshi internal constructor(builder: Builder) {
@Suppress("unused")
public fun addLast(adapter: Any): Builder = apply {
addLast(AdapterMethodsFactory.get(adapter))
addLast(AdapterMethodsFactory(adapter))
}
@CheckReturnValue

View File

@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@file:Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
package com.squareup.moshi
import com.squareup.moshi.internal.EMPTY_TYPE_ARRAY
@@ -30,6 +31,7 @@ import java.lang.reflect.WildcardType
import java.util.Collections
import java.util.Properties
import javax.annotation.CheckReturnValue
import java.lang.annotation.Annotation as JavaAnnotation
/** Factory methods for types. */
@CheckReturnValue
@@ -62,7 +64,7 @@ public object Types {
*/
@JvmStatic
public fun generatedJsonAdapterName(className: String): String {
return className.replace("$", "_") + "JsonAdapter"
return "${className.replace("$", "_")}JsonAdapter"
}
/**
@@ -81,8 +83,7 @@ public object Types {
return null
}
for (annotation in annotations) {
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
if ((jsonQualifier == (annotation as java.lang.annotation.Annotation).annotationType())) {
if ((jsonQualifier == (annotation as JavaAnnotation).annotationType())) {
val delegateAnnotations = LinkedHashSet(annotations)
delegateAnnotations.remove(annotation)
return Collections.unmodifiableSet(delegateAnnotations)
@@ -178,7 +179,7 @@ public object Types {
}
is WildcardType -> getRawType(type.upperBounds[0])
else -> {
val className = if (type == null) "null" else type.javaClass.name
val className = type?.javaClass?.name?.toString()
throw IllegalArgumentException("Expected a Class, ParameterizedType, or GenericArrayType, but <$type> is of type $className")
}
}
@@ -259,19 +260,18 @@ public object Types {
val field = clazz.getDeclaredField(fieldName)
field.isAccessible = true
val fieldAnnotations = field.declaredAnnotations
val annotations: MutableSet<Annotation> = LinkedHashSet(fieldAnnotations.size)
for (annotation in fieldAnnotations) {
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
if ((annotation as java.lang.annotation.Annotation).annotationType()
.isAnnotationPresent(JsonQualifier::class.java)
) {
annotations.add(annotation)
return buildSet(fieldAnnotations.size) {
for (annotation in fieldAnnotations) {
val hasJsonQualifier = (annotation as JavaAnnotation).annotationType()
.isAnnotationPresent(JsonQualifier::class.java)
if (hasJsonQualifier) {
add(annotation)
}
}
}
return Collections.unmodifiableSet(annotations)
} catch (e: NoSuchFieldException) {
throw IllegalArgumentException(
"Could not access field " + fieldName + " on class " + clazz.canonicalName, e
"Could not access field $fieldName on class ${clazz.canonicalName}", e
)
}
}
@@ -298,7 +298,7 @@ public object Types {
annotationType.isInstance(o)
}
"hashCode" -> 0
"toString" -> "@" + annotationType.name + "()"
"toString" -> "@${annotationType.name}()"
else -> method.invoke(proxy, *args)
}
} as T