Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert util package to Kotlin #1461

Merged
merged 21 commits into from Jan 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -78,7 +78,7 @@ public JsonAdapter<?> create(
nameStrings = new String[constants.length];
for (int i = 0; i < constants.length; i++) {
String constantName = constants[i].name();
nameStrings[i] = Util.jsonName(constantName, enumType.getField(constantName));
nameStrings[i] = Util.jsonName(enumType.getField(constantName), constantName);
}
options = JsonReader.Options.of(nameStrings);
} catch (NoSuchFieldException e) {
Expand Down
Expand Up @@ -68,7 +68,7 @@ public EnumJsonAdapter<T> withUnknownFallback(@Nullable T fallbackValue) {
nameStrings = new String[constants.length];
for (int i = 0; i < constants.length; i++) {
String constantName = constants[i].name();
nameStrings[i] = jsonName(constantName, enumType.getField(constantName));
nameStrings[i] = jsonName(enumType.getField(constantName), constantName);
ZacSweers marked this conversation as resolved.
Show resolved Hide resolved
}
options = JsonReader.Options.of(nameStrings);
} catch (NoSuchFieldException e) {
Expand Down
Expand Up @@ -39,15 +39,14 @@ import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.JsonReader
import com.squareup.moshi.JsonWriter
import com.squareup.moshi.Moshi
import com.squareup.moshi.internal.Util
import com.squareup.moshi.kotlin.codegen.api.FromJsonComponent.ParameterOnly
import com.squareup.moshi.kotlin.codegen.api.FromJsonComponent.ParameterProperty
import com.squareup.moshi.kotlin.codegen.api.FromJsonComponent.PropertyOnly
import java.lang.reflect.Constructor
import java.lang.reflect.Type
import org.objectweb.asm.Type as AsmType

private val MOSHI_UTIL = Util::class.asClassName()
private const val MOSHI_UTIL_PACKAGE = "com.squareup.moshi.internal"
private const val TO_STRING_PREFIX = "GeneratedJsonAdapter("
private const val TO_STRING_SIZE_BASE = TO_STRING_PREFIX.length + 1 // 1 is the closing paren

Expand All @@ -61,8 +60,8 @@ public class AdapterGenerator(
private companion object {
private val INT_TYPE_BLOCK = CodeBlock.of("%T::class.javaPrimitiveType", INT)
private val DEFAULT_CONSTRUCTOR_MARKER_TYPE_BLOCK = CodeBlock.of(
"%T.DEFAULT_CONSTRUCTOR_MARKER",
Util::class
"%M",
MemberName(MOSHI_UTIL_PACKAGE, "DEFAULT_CONSTRUCTOR_MARKER")
)
private val CN_MOSHI = Moshi::class.asClassName()
private val CN_TYPE = Type::class.asClassName()
Expand Down Expand Up @@ -656,8 +655,8 @@ public class AdapterGenerator(

private fun unexpectedNull(property: PropertyGenerator, reader: ParameterSpec): CodeBlock {
return CodeBlock.of(
"%T.unexpectedNull(%S, %S, %N)",
MOSHI_UTIL,
"%M(%S, %S, %N)",
MemberName(MOSHI_UTIL_PACKAGE, "unexpectedNull"),
property.localName,
property.jsonName,
reader
Expand Down Expand Up @@ -699,8 +698,8 @@ public class AdapterGenerator(
private fun FunSpec.Builder.addMissingPropertyCheck(property: PropertyGenerator, readerParam: ParameterSpec) {
val missingPropertyBlock =
CodeBlock.of(
"%T.missingProperty(%S, %S, %N)",
MOSHI_UTIL,
"%M(%S, %S, %N)",
MemberName(MOSHI_UTIL_PACKAGE, "missingProperty"),
property.localName,
property.jsonName,
readerParam
Expand Down
Expand Up @@ -1270,7 +1270,7 @@ class GeneratedAdaptersTest {
@Test fun customGenerator_withClassPresent() {
val moshi = Moshi.Builder().build()
val adapter = moshi.adapter<CustomGeneratedClass>()
val unwrapped = (adapter as NullSafeJsonAdapter<CustomGeneratedClass>).delegate()
val unwrapped = (adapter as NullSafeJsonAdapter<CustomGeneratedClass>).delegate
assertThat(unwrapped).isInstanceOf(
GeneratedAdaptersTest_CustomGeneratedClassJsonAdapter::class.java
)
Expand Down
Expand Up @@ -22,9 +22,12 @@ import com.squareup.moshi.JsonReader
import com.squareup.moshi.JsonWriter
import com.squareup.moshi.Moshi
import com.squareup.moshi.Types
import com.squareup.moshi.internal.Util
import com.squareup.moshi.internal.Util.generatedAdapter
import com.squareup.moshi.internal.Util.resolve
import com.squareup.moshi.internal.generatedAdapter
import com.squareup.moshi.internal.isPlatformType
import com.squareup.moshi.internal.jsonAnnotations
import com.squareup.moshi.internal.missingProperty
import com.squareup.moshi.internal.resolve
import com.squareup.moshi.internal.unexpectedNull
import com.squareup.moshi.rawType
import java.lang.reflect.Modifier
import java.lang.reflect.Type
Expand Down Expand Up @@ -86,7 +89,7 @@ internal class KotlinJsonAdapter<T>(
values[propertyIndex] = binding.adapter.fromJson(reader)

if (values[propertyIndex] == null && !binding.property.returnType.isMarkedNullable) {
throw Util.unexpectedNull(
throw unexpectedNull(
binding.property.name,
binding.jsonName,
reader
Expand All @@ -102,7 +105,7 @@ internal class KotlinJsonAdapter<T>(
when {
constructor.parameters[i].isOptional -> isFullInitialized = false
constructor.parameters[i].type.isMarkedNullable -> values[i] = null // Replace absent with null.
else -> throw Util.missingProperty(
else -> throw missingProperty(
constructor.parameters[i].name,
allBindings[i]?.jsonName,
reader
Expand Down Expand Up @@ -195,9 +198,9 @@ public class KotlinJsonAdapterFactory : JsonAdapter.Factory {
if (rawType.isInterface) return null
if (rawType.isEnum) return null
if (!rawType.isAnnotationPresent(KOTLIN_METADATA)) return null
if (Util.isPlatformType(rawType)) return null
if (rawType.isPlatformType) return null
try {
val generatedAdapter = generatedAdapter(moshi, type, rawType)
val generatedAdapter = moshi.generatedAdapter(type, rawType)
if (generatedAdapter != null) {
return generatedAdapter
}
Expand Down Expand Up @@ -288,10 +291,10 @@ public class KotlinJsonAdapterFactory : JsonAdapter.Factory {
}
else -> error("Not possible!")
}
val resolvedPropertyType = resolve(type, rawType, propertyType)
val resolvedPropertyType = propertyType.resolve(type, rawType)
val adapter = moshi.adapter<Any?>(
resolvedPropertyType,
Util.jsonAnnotations(allAnnotations.toTypedArray()),
allAnnotations.toTypedArray().jsonAnnotations,
property.name
)

Expand Down
6 changes: 3 additions & 3 deletions moshi/build.gradle.kts
Expand Up @@ -52,12 +52,12 @@ tasks.withType<Test>().configureEach {
tasks.withType<KotlinCompile>()
.configureEach {
kotlinOptions {
val args = mutableListOf("-Xopt-in=kotlin.contracts.ExperimentalContracts")
val toAdd = mutableListOf("-Xopt-in=kotlin.RequiresOptIn", "-Xopt-in=kotlin.contracts.ExperimentalContracts")
if (name.contains("test", true)) {
args += "-Xopt-in=kotlin.ExperimentalStdlibApi"
toAdd += "-Xopt-in=kotlin.ExperimentalStdlibApi"
}
@Suppress("SuspiciousCollectionReassignment") // It's not suspicious
freeCompilerArgs += args
freeCompilerArgs += toAdd
}
}

Expand Down
Expand Up @@ -15,7 +15,7 @@
*/
package com.squareup.moshi

import com.squareup.moshi.internal.Util
import com.squareup.moshi.internal.boxIfPrimitive
import java.lang.reflect.GenericArrayType
import java.lang.reflect.Type
import java.lang.reflect.WildcardType
Expand All @@ -42,7 +42,7 @@ public inline fun <reified T : Annotation> Set<Annotation>.nextAnnotations(): Se
public inline fun <reified T> subtypeOf(): WildcardType {
var type = typeOf<T>().javaType
if (type is Class<*>) {
type = Util.boxIfPrimitive(type)
type = type.boxIfPrimitive()
}
return Types.subtypeOf(type)
}
Expand All @@ -55,7 +55,7 @@ public inline fun <reified T> subtypeOf(): WildcardType {
public inline fun <reified T> supertypeOf(): WildcardType {
var type = typeOf<T>().javaType
if (type is Class<*>) {
type = Util.boxIfPrimitive(type)
type = type.boxIfPrimitive()
}
return Types.supertypeOf(type)
}
Expand Down
22 changes: 11 additions & 11 deletions moshi/src/main/java/com/squareup/moshi/AdapterMethodsFactory.java
Expand Up @@ -16,8 +16,8 @@
package com.squareup.moshi;

import static com.squareup.moshi.internal.Util.canonicalize;
import static com.squareup.moshi.internal.Util.jsonAnnotations;
import static com.squareup.moshi.internal.Util.typeAnnotatedWithAnnotations;
import static com.squareup.moshi.internal.Util.getJsonAnnotations;
import static com.squareup.moshi.internal.Util.toStringWithAnnotations;

import com.squareup.moshi.internal.Util;
import java.io.IOException;
Expand Down Expand Up @@ -57,7 +57,7 @@ final class AdapterMethodsFactory implements JsonAdapter.Factory {
"No "
+ missingAnnotation
+ " adapter for "
+ typeAnnotatedWithAnnotations(type, annotations),
+ toStringWithAnnotations(type, annotations),
e);
}
} else {
Expand Down Expand Up @@ -172,7 +172,7 @@ static AdapterMethod toAdapter(Object adapter, Method method) {
&& parametersAreJsonAdapters(2, parameterTypes)) {
// void pointToJson(JsonWriter jsonWriter, Point point) {
// void pointToJson(JsonWriter jsonWriter, Point point, JsonAdapter<?> adapter, ...) {
Set<? extends Annotation> qualifierAnnotations = jsonAnnotations(parameterAnnotations[1]);
Set<? extends Annotation> qualifierAnnotations = getJsonAnnotations(parameterAnnotations[1]);
return new AdapterMethod(
parameterTypes[1],
qualifierAnnotations,
Expand All @@ -190,10 +190,10 @@ public void toJson(Moshi moshi, JsonWriter writer, @Nullable Object value)

} else if (parameterTypes.length == 1 && returnType != void.class) {
// List<Integer> pointToJson(Point point) {
final Set<? extends Annotation> returnTypeAnnotations = jsonAnnotations(method);
final Set<? extends Annotation> returnTypeAnnotations = Util.getJsonAnnotations(method);
final Set<? extends Annotation> qualifierAnnotations =
jsonAnnotations(parameterAnnotations[0]);
boolean nullable = Util.hasNullable(parameterAnnotations[0]);
getJsonAnnotations(parameterAnnotations[0]);
boolean nullable = Util.getHasNullable(parameterAnnotations[0]);
return new AdapterMethod(
parameterTypes[0],
qualifierAnnotations,
Expand Down Expand Up @@ -251,7 +251,7 @@ private static boolean parametersAreJsonAdapters(int offset, Type[] parameterTyp
static AdapterMethod fromAdapter(Object adapter, Method method) {
method.setAccessible(true);
final Type returnType = method.getGenericReturnType();
final Set<? extends Annotation> returnTypeAnnotations = jsonAnnotations(method);
final Set<? extends Annotation> returnTypeAnnotations = Util.getJsonAnnotations(method);
final Type[] parameterTypes = method.getGenericParameterTypes();
Annotation[][] parameterAnnotations = method.getParameterAnnotations();

Expand All @@ -273,8 +273,8 @@ public Object fromJson(Moshi moshi, JsonReader reader)
} else if (parameterTypes.length == 1 && returnType != void.class) {
// Point pointFromJson(List<Integer> o) {
final Set<? extends Annotation> qualifierAnnotations =
jsonAnnotations(parameterAnnotations[0]);
boolean nullable = Util.hasNullable(parameterAnnotations[0]);
getJsonAnnotations(parameterAnnotations[0]);
boolean nullable = Util.getHasNullable(parameterAnnotations[0]);
return new AdapterMethod(
returnType, returnTypeAnnotations, adapter, method, parameterTypes.length, 1, nullable) {
JsonAdapter<Object> delegate;
Expand Down Expand Up @@ -354,7 +354,7 @@ public void bind(Moshi moshi, JsonAdapter.Factory factory) {
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
for (int i = adaptersOffset, size = parameterTypes.length; i < size; i++) {
Type type = ((ParameterizedType) parameterTypes[i]).getActualTypeArguments()[0];
Set<? extends Annotation> jsonAnnotations = jsonAnnotations(parameterAnnotations[i]);
Set<? extends Annotation> jsonAnnotations = getJsonAnnotations(parameterAnnotations[i]);
jsonAdapters[i - adaptersOffset] =
Types.equals(this.type, type) && annotations.equals(jsonAnnotations)
? moshi.nextAdapter(factory, type, jsonAnnotations)
Expand Down
6 changes: 3 additions & 3 deletions moshi/src/main/java/com/squareup/moshi/ClassJsonAdapter.java
Expand Up @@ -139,16 +139,16 @@ private void createFieldBindings(
if (jsonAnnotation != null && jsonAnnotation.ignore()) continue;

// Look up a type adapter for this type.
Type fieldType = resolve(type, rawType, field.getGenericType());
Set<? extends Annotation> annotations = Util.jsonAnnotations(field);
Type fieldType = resolve(field.getGenericType(), type, rawType);
Set<? extends Annotation> annotations = Util.getJsonAnnotations(field);
String fieldName = field.getName();
JsonAdapter<Object> adapter = moshi.adapter(fieldType, annotations, fieldName);

// Create the binding between field and JSON.
field.setAccessible(true);

// Store it using the field's name. If there was already a field with this name, fail!
String jsonName = jsonName(fieldName, jsonAnnotation);
String jsonName = jsonName(jsonAnnotation, fieldName);
FieldBinding<Object> fieldBinding = new FieldBinding<>(jsonName, field, adapter);
FieldBinding<?> replaced = fieldBindings.put(jsonName, fieldBinding);
if (replaced != null) {
Expand Down
26 changes: 13 additions & 13 deletions moshi/src/main/java/com/squareup/moshi/Moshi.kt
Expand Up @@ -16,12 +16,12 @@
package com.squareup.moshi

import com.squareup.moshi.Types.createJsonQualifierImplementation
import com.squareup.moshi.internal.Util
import com.squareup.moshi.internal.Util.canonicalize
import com.squareup.moshi.internal.Util.isAnnotationPresent
import com.squareup.moshi.internal.Util.removeSubtypeWildcard
import com.squareup.moshi.internal.Util.typeAnnotatedWithAnnotations
import com.squareup.moshi.internal.Util.typesMatch
import com.squareup.moshi.internal.NO_ANNOTATIONS
import com.squareup.moshi.internal.canonicalize
import com.squareup.moshi.internal.isAnnotationPresent
import com.squareup.moshi.internal.removeSubtypeWildcard
import com.squareup.moshi.internal.toStringWithAnnotations
import com.squareup.moshi.internal.typesMatch
import java.lang.reflect.Type
import javax.annotation.CheckReturnValue

Expand All @@ -42,10 +42,10 @@ public class Moshi internal constructor(builder: Builder) {

/** Returns a JSON adapter for `type`, creating it if necessary. */
@CheckReturnValue
public fun <T> adapter(type: Type): JsonAdapter<T> = adapter(type, Util.NO_ANNOTATIONS)
public fun <T> adapter(type: Type): JsonAdapter<T> = adapter(type, NO_ANNOTATIONS)

@CheckReturnValue
public fun <T> adapter(type: Class<T>): JsonAdapter<T> = adapter(type, Util.NO_ANNOTATIONS)
public fun <T> adapter(type: Class<T>): JsonAdapter<T> = adapter(type, NO_ANNOTATIONS)

@CheckReturnValue
public fun <T> adapter(type: Type, annotationType: Class<out Annotation>): JsonAdapter<T> =
Expand Down Expand Up @@ -78,7 +78,7 @@ public class Moshi internal constructor(builder: Builder) {
annotations: Set<Annotation>,
fieldName: String?
): JsonAdapter<T> {
val cleanedType = removeSubtypeWildcard(canonicalize(type))
val cleanedType = type.canonicalize().removeSubtypeWildcard()

// If there's an equivalent adapter in the cache, we're done!
val cacheKey = cacheKey(cleanedType, annotations)
Expand Down Expand Up @@ -107,7 +107,7 @@ public class Moshi internal constructor(builder: Builder) {
success = true
return result
}
throw IllegalArgumentException("No JsonAdapter for ${typeAnnotatedWithAnnotations(type, annotations)}")
throw IllegalArgumentException("No JsonAdapter for ${type.toStringWithAnnotations(annotations)}")
} catch (e: IllegalArgumentException) {
throw lookupChain.exceptionWithLookupStack(e)
} finally {
Expand All @@ -121,15 +121,15 @@ public class Moshi internal constructor(builder: Builder) {
type: Type,
annotations: Set<Annotation>
): JsonAdapter<T> {
val cleanedType = removeSubtypeWildcard(canonicalize(type))
val cleanedType = type.canonicalize().removeSubtypeWildcard()
val skipPastIndex = factories.indexOf(skipPast)
require(skipPastIndex != -1) { "Unable to skip past unknown factory $skipPast" }
for (i in (skipPastIndex + 1) until factories.size) {
@Suppress("UNCHECKED_CAST") // Factories are required to return only matching JsonAdapters.
val result = factories[i].create(cleanedType, annotations, this) as JsonAdapter<T>?
if (result != null) return result
}
throw IllegalArgumentException("No next JsonAdapter for ${typeAnnotatedWithAnnotations(cleanedType, annotations)}")
throw IllegalArgumentException("No next JsonAdapter for ${cleanedType.toStringWithAnnotations(annotations)}")
}

/** Returns a new builder containing all custom factories used by the current instance. */
Expand Down Expand Up @@ -354,7 +354,7 @@ public class Moshi internal constructor(builder: Builder) {
require(annotation.isAnnotationPresent(JsonQualifier::class.java)) { "$annotation does not have @JsonQualifier" }
require(annotation.declaredMethods.isEmpty()) { "Use JsonAdapter.Factory for annotations with elements" }
return JsonAdapter.Factory { targetType, annotations, _ ->
if (typesMatch(type, targetType) && annotations.size == 1 && isAnnotationPresent(annotations, annotation)) {
if (typesMatch(type, targetType) && annotations.size == 1 && annotations.isAnnotationPresent(annotation)) {
jsonAdapter
} else {
null
Expand Down
Expand Up @@ -275,7 +275,7 @@ static final class EnumJsonAdapter<T extends Enum<T>> extends JsonAdapter<T> {
for (int i = 0; i < constants.length; i++) {
T constant = constants[i];
String constantName = constant.name();
nameStrings[i] = Util.jsonName(constantName, enumType.getField(constantName));
nameStrings[i] = Util.jsonName(enumType.getField(constantName), constantName);
}
options = JsonReader.Options.of(nameStrings);
} catch (NoSuchFieldException e) {
Expand Down