(
- val name: String,
- val adapter: JsonAdapter,
- val property: KProperty1,
- val parameter: KParameter?) {
- fun get(value: K) = property.get(value)
-
- fun set(result: K, value: P) {
- if (value !== ABSENT_VALUE) {
- (property as KMutableProperty1).set(result, value)
- }
- }
- }
-
- /** A simple [Map] that uses parameter indexes instead of sorting or hashing. */
- class IndexedParameterMap(val parameterKeys: List, val parameterValues: Array)
- : AbstractMap() {
-
- override val entries: Set>
- get() {
- val allPossibleEntries = parameterKeys.mapIndexed { index, value ->
- SimpleEntry(value, parameterValues[index])
- }
- return allPossibleEntries.filterTo(LinkedHashSet>()) {
- it.value !== ABSENT_VALUE
- }
- }
-
- override fun containsKey(key: KParameter) = parameterValues[key.index] !== ABSENT_VALUE
-
- override fun get(key: KParameter): Any? {
- val value = parameterValues[key.index]
- return if (value !== ABSENT_VALUE) value else null
- }
- }
-}
-
-class KotlinJsonAdapterFactory : JsonAdapter.Factory {
- override fun create(type: Type, annotations: MutableSet, moshi: Moshi)
- : JsonAdapter<*>? {
- 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
-
- 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>()
-
- for (property in rawTypeKotlin.memberProperties) {
- val parameter = parametersByName[property.name]
-
- if (Modifier.isTransient(property.javaField?.modifiers ?: 0)) {
- if (parameter != null && !parameter.isOptional) {
- throw IllegalArgumentException(
- "No default value for transient constructor $parameter")
- }
- continue
- }
-
- if (property !is KMutableProperty1 && parameter == null) continue
-
- property.isAccessible = true
- var allAnnotations = property.annotations
- var jsonAnnotation = property.findAnnotation()
-
- if (parameter != null) {
- allAnnotations += parameter.annotations
- if (jsonAnnotation == null) {
- jsonAnnotation = parameter.findAnnotation()
- }
- }
-
- val name = jsonAnnotation?.name ?: property.name
- val adapter = moshi.adapter(
- property.returnType.javaType, Util.jsonAnnotations(allAnnotations.toTypedArray()))
-
- bindingsByName[property.name] =
- KotlinJsonAdapter.Binding(name, adapter, property as KProperty1, parameter)
- }
-
- val bindings = ArrayList?>()
-
- for (parameter in constructor.parameters) {
- val binding = bindingsByName.remove(parameter.name)
- if (binding == null && !parameter.isOptional) {
- throw IllegalArgumentException("No property for required constructor ${parameter}")
- }
- bindings += binding
- }
-
- bindings += bindingsByName.values
-
- val options = JsonReader.Options.of(*bindings.map { it?.name ?: "\u0000" }.toTypedArray())
- return KotlinJsonAdapter(constructor, bindings, options).nullSafe()
- }
-}
+@Deprecated(
+ message = "this moved to avoid a package name conflict in the Java Platform Module System.",
+ replaceWith = ReplaceWith("com.squareup.moshi.kotlin.KotlinJsonAdapterFactory")
+)
+class KotlinJsonAdapterFactory
+ : JsonAdapter.Factory by com.squareup.moshi.kotlin.KotlinJsonAdapterFactory()
diff --git a/kotlin/src/main/java/com/squareup/moshi/kotlin/KotlinJsonAdapter.kt b/kotlin/src/main/java/com/squareup/moshi/kotlin/KotlinJsonAdapter.kt
new file mode 100644
index 0000000..b50a8c1
--- /dev/null
+++ b/kotlin/src/main/java/com/squareup/moshi/kotlin/KotlinJsonAdapter.kt
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2017 Square, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.squareup.moshi.kotlin
+
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonAdapter
+import com.squareup.moshi.JsonDataException
+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 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
+import kotlin.reflect.KProperty1
+import kotlin.reflect.full.findAnnotation
+import kotlin.reflect.full.memberProperties
+import kotlin.reflect.full.primaryConstructor
+import kotlin.reflect.jvm.isAccessible
+import kotlin.reflect.jvm.javaField
+import kotlin.reflect.jvm.javaType
+
+/** Classes annotated with this are eligible for this adapter. */
+private val KOTLIN_METADATA = Class.forName("kotlin.Metadata") as Class
+
+/**
+ * Placeholder value used when a field is absent from the JSON. Note that this code
+ * distinguishes between absent values and present-but-null values.
+ */
+private object ABSENT_VALUE
+
+/**
+ * This class encodes Kotlin classes using their properties. It decodes them by first invoking the
+ * constructor, and then by setting any additional properties that exist, if any.
+ */
+internal class KotlinJsonAdapter(
+ val constructor: KFunction,
+ val bindings: List?>,
+ val options: JsonReader.Options) : JsonAdapter() {
+
+ override fun fromJson(reader: JsonReader): T {
+ val constructorSize = constructor.parameters.size
+
+ // Read each value into its slot in the array.
+ val values = Array(bindings.size) { ABSENT_VALUE }
+ reader.beginObject()
+ while (reader.hasNext()) {
+ val index = reader.selectName(options)
+ val binding = if (index != -1) bindings[index] else null
+
+ if (binding == null) {
+ reader.nextName()
+ reader.skipValue()
+ continue
+ }
+
+ if (values[index] !== ABSENT_VALUE) {
+ throw JsonDataException(
+ "Multiple values for ${constructor.parameters[index].name} at ${reader.path}")
+ }
+
+ values[index] = binding.adapter.fromJson(reader)
+ }
+ reader.endObject()
+
+ // Confirm all parameters are present, optional, or nullable.
+ for (i in 0 until constructorSize) {
+ if (values[i] === ABSENT_VALUE && !constructor.parameters[i].isOptional) {
+ if (!constructor.parameters[i].type.isMarkedNullable) {
+ throw JsonDataException(
+ "Required value ${constructor.parameters[i].name} missing at ${reader.path}")
+ }
+ values[i] = null // Replace absent with null.
+ } else if (values[i] == null && !constructor.parameters[i].type.isMarkedNullable) {
+ throw JsonDataException("Non-null value ${constructor.parameters[i].name} " +
+ "was null at ${reader.path}")
+ }
+ }
+
+ // Call the constructor using a Map so that absent optionals get defaults.
+ val result = constructor.callBy(IndexedParameterMap(constructor.parameters, values))
+
+ // Set remaining properties.
+ for (i in constructorSize until bindings.size) {
+ val binding = bindings[i]!!
+ val value = values[i]
+ if (value == null && !binding.property.returnType.isMarkedNullable) {
+ throw JsonDataException("Non-null value ${binding.property.name} " +
+ "was null at ${reader.path}")
+ }
+ binding.set(result, value)
+ }
+
+ return result
+ }
+
+ override fun toJson(writer: JsonWriter, value: T?) {
+ if (value == null) throw NullPointerException("value == null")
+
+ writer.beginObject()
+ for (binding in bindings) {
+ if (binding == null) continue // Skip constructor parameters that aren't properties.
+
+ writer.name(binding.name)
+ binding.adapter.toJson(writer, binding.get(value))
+ }
+ writer.endObject()
+ }
+
+ override fun toString() = "KotlinJsonAdapter(${constructor.returnType})"
+
+ data class Binding(
+ val name: String,
+ val adapter: JsonAdapter,
+ val property: KProperty1,
+ val parameter: KParameter?) {
+ fun get(value: K) = property.get(value)
+
+ fun set(result: K, value: P) {
+ if (value !== ABSENT_VALUE) {
+ (property as KMutableProperty1).set(result, value)
+ }
+ }
+ }
+
+ /** A simple [Map] that uses parameter indexes instead of sorting or hashing. */
+ class IndexedParameterMap(val parameterKeys: List, val parameterValues: Array)
+ : AbstractMap() {
+
+ override val entries: Set>
+ get() {
+ val allPossibleEntries = parameterKeys.mapIndexed { index, value ->
+ SimpleEntry(value, parameterValues[index])
+ }
+ return allPossibleEntries.filterTo(LinkedHashSet>()) {
+ it.value !== ABSENT_VALUE
+ }
+ }
+
+ override fun containsKey(key: KParameter) = parameterValues[key.index] !== ABSENT_VALUE
+
+ override fun get(key: KParameter): Any? {
+ val value = parameterValues[key.index]
+ return if (value !== ABSENT_VALUE) value else null
+ }
+ }
+}
+
+class KotlinJsonAdapterFactory : JsonAdapter.Factory {
+ override fun create(type: Type, annotations: MutableSet, moshi: Moshi)
+ : JsonAdapter<*>? {
+ 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 (Util.isPlatformType(rawType)) 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>()
+
+ for (property in rawTypeKotlin.memberProperties) {
+ val parameter = parametersByName[property.name]
+
+ if (Modifier.isTransient(property.javaField?.modifiers ?: 0)) {
+ if (parameter != null && !parameter.isOptional) {
+ throw IllegalArgumentException(
+ "No default value for transient constructor $parameter")
+ }
+ continue
+ }
+
+ if (property !is KMutableProperty1 && parameter == null) continue
+
+ property.isAccessible = true
+ var allAnnotations = property.annotations
+ var jsonAnnotation = property.findAnnotation()
+
+ if (parameter != null) {
+ allAnnotations += parameter.annotations
+ if (jsonAnnotation == null) {
+ jsonAnnotation = parameter.findAnnotation()
+ }
+ }
+
+ val name = jsonAnnotation?.name ?: property.name
+ val adapter = moshi.adapter(
+ property.returnType.javaType, Util.jsonAnnotations(allAnnotations.toTypedArray()))
+
+ bindingsByName[property.name] =
+ KotlinJsonAdapter.Binding(name, adapter, property as KProperty1, parameter)
+ }
+
+ val bindings = ArrayList?>()
+
+ for (parameter in constructor.parameters) {
+ val binding = bindingsByName.remove(parameter.name)
+ if (binding == null && !parameter.isOptional) {
+ throw IllegalArgumentException("No property for required constructor ${parameter}")
+ }
+ bindings += binding
+ }
+
+ bindings += bindingsByName.values
+
+ val options = JsonReader.Options.of(*bindings.map { it?.name ?: "\u0000" }.toTypedArray())
+ return KotlinJsonAdapter(constructor, bindings, options).nullSafe()
+ }
+}
diff --git a/kotlin/src/test/java/com/squareup/moshi/KotlinJsonAdapterTest.kt b/kotlin/src/test/java/com/squareup/moshi/kotlin/KotlinJsonAdapterTest.kt
similarity index 96%
rename from kotlin/src/test/java/com/squareup/moshi/KotlinJsonAdapterTest.kt
rename to kotlin/src/test/java/com/squareup/moshi/kotlin/KotlinJsonAdapterTest.kt
index 1af9183..e25f23b 100644
--- a/kotlin/src/test/java/com/squareup/moshi/KotlinJsonAdapterTest.kt
+++ b/kotlin/src/test/java/com/squareup/moshi/kotlin/KotlinJsonAdapterTest.kt
@@ -13,8 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.squareup.moshi
+package com.squareup.moshi.kotlin
+import com.squareup.moshi.FromJson
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonDataException
+import com.squareup.moshi.JsonQualifier
+import com.squareup.moshi.Moshi
+import com.squareup.moshi.ToJson
import org.assertj.core.api.Assertions.assertThat
import org.junit.Assert.fail
import org.junit.Test
@@ -315,7 +321,7 @@ class KotlinJsonAdapterTest {
} catch (expected: IllegalArgumentException) {
assertThat(expected).hasMessage("No default value for transient constructor parameter #0 " +
"a of fun (kotlin.Int): " +
- "com.squareup.moshi.KotlinJsonAdapterTest.RequiredTransientConstructorParameter")
+ "com.squareup.moshi.kotlin.KotlinJsonAdapterTest.RequiredTransientConstructorParameter")
}
}
@@ -587,7 +593,7 @@ class KotlinJsonAdapterTest {
fail()
} catch (e: IllegalArgumentException) {
assertThat(e).hasMessage("No JsonAdapter for interface " +
- "com.squareup.moshi.KotlinJsonAdapterTest\$Interface annotated []")
+ "com.squareup.moshi.kotlin.KotlinJsonAdapterTest\$Interface annotated []")
}
}
@@ -599,8 +605,8 @@ class KotlinJsonAdapterTest {
moshi.adapter(AbstractClass::class.java)
fail()
} catch (e: IllegalArgumentException) {
- assertThat(e).hasMessage(
- "Cannot serialize abstract class com.squareup.moshi.KotlinJsonAdapterTest\$AbstractClass")
+ assertThat(e).hasMessage("Cannot serialize abstract class " +
+ "com.squareup.moshi.kotlin.KotlinJsonAdapterTest\$AbstractClass")
}
}
@@ -612,8 +618,8 @@ class KotlinJsonAdapterTest {
moshi.adapter(InnerClass::class.java)
fail()
} catch (e: IllegalArgumentException) {
- assertThat(e).hasMessage(
- "Cannot serialize inner class com.squareup.moshi.KotlinJsonAdapterTest\$InnerClass")
+ assertThat(e).hasMessage("Cannot serialize inner class " +
+ "com.squareup.moshi.kotlin.KotlinJsonAdapterTest\$InnerClass")
}
}
@@ -627,7 +633,7 @@ class KotlinJsonAdapterTest {
fail()
} catch (e: IllegalArgumentException) {
assertThat(e).hasMessage("Cannot serialize local class or object expression " +
- "com.squareup.moshi.KotlinJsonAdapterTest\$localClassesNotSupported\$LocalClass")
+ "com.squareup.moshi.kotlin.KotlinJsonAdapterTest\$localClassesNotSupported\$LocalClass")
}
}
@@ -638,7 +644,7 @@ class KotlinJsonAdapterTest {
fail()
} catch (e: IllegalArgumentException) {
assertThat(e).hasMessage("Cannot serialize object declaration " +
- "com.squareup.moshi.KotlinJsonAdapterTest\$ObjectDeclaration")
+ "com.squareup.moshi.kotlin.KotlinJsonAdapterTest\$ObjectDeclaration")
}
}
@@ -656,7 +662,8 @@ class KotlinJsonAdapterTest {
fail()
} catch (e: IllegalArgumentException) {
assertThat(e).hasMessage("Cannot serialize local class or object expression " +
- "com.squareup.moshi.KotlinJsonAdapterTest\$objectExpressionsNotSupported\$expression$1")
+ "com.squareup.moshi.kotlin.KotlinJsonAdapterTest\$objectExpressionsNotSupported" +
+ "\$expression$1")
}
}
diff --git a/moshi/pom.xml b/moshi/pom.xml
index a915c33..ad32ad4 100644
--- a/moshi/pom.xml
+++ b/moshi/pom.xml
@@ -33,4 +33,20 @@
test
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+
+ com.squareup.moshi
+
+
+
+
+
+
diff --git a/moshi/src/main/java/com/squareup/moshi/AdapterMethodsFactory.java b/moshi/src/main/java/com/squareup/moshi/AdapterMethodsFactory.java
index 5bfc3bc..266e018 100644
--- a/moshi/src/main/java/com/squareup/moshi/AdapterMethodsFactory.java
+++ b/moshi/src/main/java/com/squareup/moshi/AdapterMethodsFactory.java
@@ -15,6 +15,7 @@
*/
package com.squareup.moshi;
+import com.squareup.moshi.internal.Util;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
@@ -26,7 +27,7 @@ import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;
-import static com.squareup.moshi.Util.jsonAnnotations;
+import static com.squareup.moshi.internal.Util.jsonAnnotations;
final class AdapterMethodsFactory implements JsonAdapter.Factory {
private final List toAdapters;
diff --git a/moshi/src/main/java/com/squareup/moshi/ClassJsonAdapter.java b/moshi/src/main/java/com/squareup/moshi/ClassJsonAdapter.java
index 76c929d..1508240 100644
--- a/moshi/src/main/java/com/squareup/moshi/ClassJsonAdapter.java
+++ b/moshi/src/main/java/com/squareup/moshi/ClassJsonAdapter.java
@@ -15,6 +15,7 @@
*/
package com.squareup.moshi;
+import com.squareup.moshi.internal.Util;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
@@ -48,7 +49,7 @@ final class ClassJsonAdapter extends JsonAdapter {
if (!(type instanceof Class)) return null;
Class> rawType = (Class>) type;
if (rawType.isInterface() || rawType.isEnum()) return null;
- if (isPlatformType(rawType) && !Types.isAllowedPlatformType(rawType)) {
+ if (Util.isPlatformType(rawType) && !Types.isAllowedPlatformType(rawType)) {
throw new IllegalArgumentException("Platform "
+ type
+ " annotated "
@@ -83,7 +84,7 @@ final class ClassJsonAdapter extends JsonAdapter {
private void createFieldBindings(
Moshi moshi, Type type, Map> fieldBindings) {
Class> rawType = Types.getRawType(type);
- boolean platformType = isPlatformType(rawType);
+ boolean platformType = Util.isPlatformType(rawType);
for (Field field : rawType.getDeclaredFields()) {
if (!includeField(platformType, field.getModifiers())) continue;
@@ -115,19 +116,6 @@ final class ClassJsonAdapter extends JsonAdapter {
}
};
- /**
- * Returns true if {@code rawType} is built in. We don't reflect on private fields of platform
- * types because they're unspecified and likely to be different on Java vs. Android.
- */
- static boolean isPlatformType(Class> rawType) {
- String name = rawType.getName();
- return name.startsWith("android.")
- || name.startsWith("java.")
- || name.startsWith("javax.")
- || name.startsWith("kotlin.")
- || name.startsWith("scala.");
- }
-
private final ClassFactory classFactory;
private final FieldBinding>[] fieldsArray;
private final JsonReader.Options options;
diff --git a/moshi/src/main/java/com/squareup/moshi/Moshi.java b/moshi/src/main/java/com/squareup/moshi/Moshi.java
index 7ccfb92..315f6fb 100644
--- a/moshi/src/main/java/com/squareup/moshi/Moshi.java
+++ b/moshi/src/main/java/com/squareup/moshi/Moshi.java
@@ -15,6 +15,7 @@
*/
package com.squareup.moshi;
+import com.squareup.moshi.internal.Util;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
diff --git a/moshi/src/main/java/com/squareup/moshi/StandardJsonAdapters.java b/moshi/src/main/java/com/squareup/moshi/StandardJsonAdapters.java
index 526dac4..5a7eb46 100644
--- a/moshi/src/main/java/com/squareup/moshi/StandardJsonAdapters.java
+++ b/moshi/src/main/java/com/squareup/moshi/StandardJsonAdapters.java
@@ -15,6 +15,7 @@
*/
package com.squareup.moshi;
+import com.squareup.moshi.internal.Util;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
diff --git a/moshi/src/main/java/com/squareup/moshi/Util.java b/moshi/src/main/java/com/squareup/moshi/internal/Util.java
similarity index 80%
rename from moshi/src/main/java/com/squareup/moshi/Util.java
rename to moshi/src/main/java/com/squareup/moshi/internal/Util.java
index 0d93867..8ee3707 100644
--- a/moshi/src/main/java/com/squareup/moshi/Util.java
+++ b/moshi/src/main/java/com/squareup/moshi/internal/Util.java
@@ -13,8 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.squareup.moshi;
+package com.squareup.moshi.internal;
+import com.squareup.moshi.JsonQualifier;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Type;
@@ -22,7 +23,7 @@ import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
-final class Util {
+public final class Util {
public static final Set NO_ANNOTATIONS = Collections.emptySet();
private Util() {
@@ -66,4 +67,17 @@ final class Util {
}
return false;
}
+
+ /**
+ * Returns true if {@code rawType} is built in. We don't reflect on private fields of platform
+ * types because they're unspecified and likely to be different on Java vs. Android.
+ */
+ public static boolean isPlatformType(Class> rawType) {
+ String name = rawType.getName();
+ return name.startsWith("android.")
+ || name.startsWith("java.")
+ || name.startsWith("javax.")
+ || name.startsWith("kotlin.")
+ || name.startsWith("scala.");
+ }
}
diff --git a/moshi/src/test/java/com/squareup/moshi/CircularAdaptersTest.java b/moshi/src/test/java/com/squareup/moshi/CircularAdaptersTest.java
index 14256f3..00f0363 100644
--- a/moshi/src/test/java/com/squareup/moshi/CircularAdaptersTest.java
+++ b/moshi/src/test/java/com/squareup/moshi/CircularAdaptersTest.java
@@ -15,6 +15,7 @@
*/
package com.squareup.moshi;
+import com.squareup.moshi.internal.Util;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
diff --git a/moshi/src/test/java/com/squareup/moshi/ClassJsonAdapterTest.java b/moshi/src/test/java/com/squareup/moshi/ClassJsonAdapterTest.java
index ff28f28..5a6fa24 100644
--- a/moshi/src/test/java/com/squareup/moshi/ClassJsonAdapterTest.java
+++ b/moshi/src/test/java/com/squareup/moshi/ClassJsonAdapterTest.java
@@ -25,7 +25,7 @@ import okio.Buffer;
import org.junit.Test;
import static com.squareup.moshi.TestUtil.newReader;
-import static com.squareup.moshi.Util.NO_ANNOTATIONS;
+import static com.squareup.moshi.internal.Util.NO_ANNOTATIONS;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
diff --git a/moshi/src/test/java/com/squareup/moshi/MapJsonAdapterTest.java b/moshi/src/test/java/com/squareup/moshi/MapJsonAdapterTest.java
index 68a85c3..dd3e796 100644
--- a/moshi/src/test/java/com/squareup/moshi/MapJsonAdapterTest.java
+++ b/moshi/src/test/java/com/squareup/moshi/MapJsonAdapterTest.java
@@ -26,7 +26,7 @@ import org.assertj.core.data.MapEntry;
import org.junit.Test;
import static com.squareup.moshi.TestUtil.newReader;
-import static com.squareup.moshi.Util.NO_ANNOTATIONS;
+import static com.squareup.moshi.internal.Util.NO_ANNOTATIONS;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
diff --git a/moshi/src/test/java/com/squareup/moshi/MoshiTest.java b/moshi/src/test/java/com/squareup/moshi/MoshiTest.java
index 66a1428..12be431 100644
--- a/moshi/src/test/java/com/squareup/moshi/MoshiTest.java
+++ b/moshi/src/test/java/com/squareup/moshi/MoshiTest.java
@@ -16,6 +16,7 @@
package com.squareup.moshi;
import android.util.Pair;
+import com.squareup.moshi.internal.Util;
import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;