Import jsr305 and use it to mark @Nullable stuff. (#297)
This commit is contained in:
parent
dac5f695b3
commit
c65b3bf1cb
26 changed files with 149 additions and 92 deletions
|
@ -12,6 +12,11 @@
|
|||
<artifactId>moshi-examples</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>jsr305</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.moshi</groupId>
|
||||
<artifactId>moshi</artifactId>
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.io.IOException;
|
|||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public final class DefaultOnDataMismatchAdapter<T> extends JsonAdapter<T> {
|
||||
private final JsonAdapter<T> delegate;
|
||||
|
@ -54,7 +55,7 @@ public final class DefaultOnDataMismatchAdapter<T> extends JsonAdapter<T> {
|
|||
|
||||
public static <T> Factory newFactory(final Class<T> type, final T defaultValue) {
|
||||
return new Factory() {
|
||||
@Override public JsonAdapter<?> create(
|
||||
@Override public @Nullable JsonAdapter<?> create(
|
||||
Type requestedType, Set<? extends Annotation> annotations, Moshi moshi) {
|
||||
if (type != requestedType) return null;
|
||||
JsonAdapter<T> delegate = moshi.nextAdapter(this, type, annotations);
|
||||
|
|
|
@ -28,6 +28,7 @@ import java.lang.annotation.Annotation;
|
|||
import java.lang.annotation.Retention;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
|
@ -51,8 +52,8 @@ final class Unwrap {
|
|||
|
||||
public static final class EnvelopeJsonAdapter extends JsonAdapter<Object> {
|
||||
public static final JsonAdapter.Factory FACTORY = new Factory() {
|
||||
@Override
|
||||
public JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations, Moshi moshi) {
|
||||
@Override public @Nullable JsonAdapter<?> create(
|
||||
Type type, Set<? extends Annotation> annotations, Moshi moshi) {
|
||||
Set<? extends Annotation> delegateAnnotations =
|
||||
Types.nextAnnotations(annotations, Enveloped.class);
|
||||
if (delegateAnnotations == null) {
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
/** Moshi code samples. */
|
||||
@javax.annotation.ParametersAreNonnullByDefault
|
||||
package com.squareup.moshi.recipes;
|
|
@ -95,7 +95,9 @@ internal class KotlinJsonAdapter<T>(
|
|||
return result
|
||||
}
|
||||
|
||||
override fun toJson(writer: JsonWriter, value: T) {
|
||||
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.
|
||||
|
@ -202,6 +204,6 @@ object KotlinJsonAdapterFactory : JsonAdapter.Factory {
|
|||
bindings += bindingsByName.values
|
||||
|
||||
val options = JsonReader.Options.of(*bindings.map { it?.name ?: "\u0000" }.toTypedArray())
|
||||
return KotlinJsonAdapter(constructor, bindings, options)
|
||||
return KotlinJsonAdapter(constructor, bindings, options).nullSafe()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ class KotlinJsonAdapterTest {
|
|||
val encoded = ConstructorParameters(3, 5)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("{\"a\":3,\"b\":5}")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":4,\"b\":6}")
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":4,\"b\":6}")!!
|
||||
assertThat(decoded.a).isEqualTo(4)
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ class KotlinJsonAdapterTest {
|
|||
encoded.b = 5
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("{\"a\":3,\"b\":5}")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":3,\"b\":5}")
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":3,\"b\":5}")!!
|
||||
assertThat(decoded.a).isEqualTo(3)
|
||||
assertThat(decoded.b).isEqualTo(5)
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ class KotlinJsonAdapterTest {
|
|||
encoded.b = 5
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("{\"a\":3,\"b\":5}")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":4,\"b\":6}")
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":4,\"b\":6}")!!
|
||||
assertThat(decoded.a).isEqualTo(4)
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ class KotlinJsonAdapterTest {
|
|||
val encoded = ImmutableConstructorParameters(3, 5)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("{\"a\":3,\"b\":5}")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":4,\"b\":6}")
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":4,\"b\":6}")!!
|
||||
assertThat(decoded.a).isEqualTo(4)
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ class KotlinJsonAdapterTest {
|
|||
val encoded = ImmutableProperties(3, 5)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("{\"a\":3,\"b\":5}")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":3,\"b\":5}")
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":3,\"b\":5}")!!
|
||||
assertThat(decoded.a).isEqualTo(3)
|
||||
assertThat(decoded.b).isEqualTo(5)
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ class KotlinJsonAdapterTest {
|
|||
val encoded = ConstructorDefaultValues(3, 5)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("{\"a\":3,\"b\":5}")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("{\"b\":6}")
|
||||
val decoded = jsonAdapter.fromJson("{\"b\":6}")!!
|
||||
assertThat(decoded.a).isEqualTo(-1)
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ class KotlinJsonAdapterTest {
|
|||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("{\"b\":5}")
|
||||
assertThat(jsonAdapter.serializeNulls().toJson(encoded)).isEqualTo("{\"a\":null,\"b\":5}")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":null,\"b\":6}")
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":null,\"b\":6}")!!
|
||||
assertThat(decoded.a).isEqualTo(null)
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
}
|
||||
|
@ -170,7 +170,7 @@ class KotlinJsonAdapterTest {
|
|||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("{\"b\":5}")
|
||||
assertThat(jsonAdapter.serializeNulls().toJson(encoded)).isEqualTo("{\"a\":null,\"b\":5}")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("{\"b\":6}")
|
||||
val decoded = jsonAdapter.fromJson("{\"b\":6}")!!
|
||||
assertThat(decoded.a).isNull()
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
}
|
||||
|
@ -201,7 +201,7 @@ class KotlinJsonAdapterTest {
|
|||
val encoded = ConstructorParameterWithQualifier("Android", "Banana")
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("{\"a\":\"ANDROID\",\"b\":\"Banana\"}")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":\"Android\",\"b\":\"Banana\"}")
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":\"Android\",\"b\":\"Banana\"}")!!
|
||||
assertThat(decoded.a).isEqualTo("android")
|
||||
assertThat(decoded.b).isEqualTo("Banana")
|
||||
}
|
||||
|
@ -220,7 +220,7 @@ class KotlinJsonAdapterTest {
|
|||
encoded.b = "Banana"
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("{\"a\":\"ANDROID\",\"b\":\"Banana\"}")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":\"Android\",\"b\":\"Banana\"}")
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":\"Android\",\"b\":\"Banana\"}")!!
|
||||
assertThat(decoded.a).isEqualTo("android")
|
||||
assertThat(decoded.b).isEqualTo("Banana")
|
||||
}
|
||||
|
@ -237,7 +237,7 @@ class KotlinJsonAdapterTest {
|
|||
val encoded = ConstructorParameterWithJsonName(3, 5)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("{\"key a\":3,\"b\":5}")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("{\"key a\":4,\"b\":6}")
|
||||
val decoded = jsonAdapter.fromJson("{\"key a\":4,\"b\":6}")!!
|
||||
assertThat(decoded.a).isEqualTo(4)
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
}
|
||||
|
@ -253,7 +253,7 @@ class KotlinJsonAdapterTest {
|
|||
encoded.b = 5
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("{\"key a\":3,\"b\":5}")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("{\"key a\":4,\"b\":6}")
|
||||
val decoded = jsonAdapter.fromJson("{\"key a\":4,\"b\":6}")!!
|
||||
assertThat(decoded.a).isEqualTo(4)
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
}
|
||||
|
@ -270,7 +270,7 @@ class KotlinJsonAdapterTest {
|
|||
val encoded = TransientConstructorParameter(3, 5)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("{\"b\":5}")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":4,\"b\":6}")
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":4,\"b\":6}")!!
|
||||
assertThat(decoded.a).isEqualTo(-1)
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
}
|
||||
|
@ -286,7 +286,7 @@ class KotlinJsonAdapterTest {
|
|||
encoded.b = 5
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("{\"b\":5}")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":4,\"b\":6}")
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":4,\"b\":6}")!!
|
||||
assertThat(decoded.a).isEqualTo(-1)
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
}
|
||||
|
@ -303,7 +303,7 @@ class KotlinJsonAdapterTest {
|
|||
val encoded = SubtypeConstructorParameters(3, 5)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("{\"a\":3,\"b\":5}")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":4,\"b\":6}")
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":4,\"b\":6}")!!
|
||||
assertThat(decoded.a).isEqualTo(4)
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
}
|
||||
|
@ -321,7 +321,7 @@ class KotlinJsonAdapterTest {
|
|||
encoded.b = 5
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("{\"b\":5,\"a\":3}")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":4,\"b\":6}")
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":4,\"b\":6}")!!
|
||||
assertThat(decoded.a).isEqualTo(4)
|
||||
assertThat(decoded.b).isEqualTo(6)
|
||||
}
|
||||
|
@ -341,7 +341,7 @@ class KotlinJsonAdapterTest {
|
|||
val encoded = ExtendsPlatformClassWithPrivateField(3)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("{\"a\":3}")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":4,\"id\":\"B\"}")
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":4,\"id\":\"B\"}")!!
|
||||
assertThat(decoded.a).isEqualTo(4)
|
||||
assertThat(decoded.id).isEqualTo("C")
|
||||
}
|
||||
|
@ -355,7 +355,7 @@ class KotlinJsonAdapterTest {
|
|||
val encoded = ExtendsPlatformClassWithProtectedField(3)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("{\"a\":3,\"buf\":[0,0],\"count\":0}")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":4,\"buf\":[0,0],\"size\":0}")
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":4,\"buf\":[0,0],\"size\":0}")!!
|
||||
assertThat(decoded.a).isEqualTo(4)
|
||||
assertThat(decoded.buf()).isEqualTo(ByteArray(2, { 0 }))
|
||||
assertThat(decoded.count()).isEqualTo(0)
|
||||
|
@ -384,7 +384,7 @@ class KotlinJsonAdapterTest {
|
|||
val encoded = PrivateConstructorParameters(3, 5)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("{\"a\":3,\"b\":5}")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":4,\"b\":6}")
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":4,\"b\":6}")!!
|
||||
assertThat(decoded.a()).isEqualTo(4)
|
||||
assertThat(decoded.b()).isEqualTo(6)
|
||||
}
|
||||
|
@ -401,7 +401,7 @@ class KotlinJsonAdapterTest {
|
|||
val encoded = PrivateConstructor.newInstance(3, 5)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("{\"a\":3,\"b\":5}")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":4,\"b\":6}")
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":4,\"b\":6}")!!
|
||||
assertThat(decoded.a()).isEqualTo(4)
|
||||
assertThat(decoded.b()).isEqualTo(6)
|
||||
}
|
||||
|
@ -423,7 +423,7 @@ class KotlinJsonAdapterTest {
|
|||
encoded.b(5)
|
||||
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("{\"a\":3,\"b\":5}")
|
||||
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":4,\"b\":6}")
|
||||
val decoded = jsonAdapter.fromJson("{\"a\":4,\"b\":6}")!!
|
||||
assertThat(decoded.a()).isEqualTo(4)
|
||||
assertThat(decoded.b()).isEqualTo(6)
|
||||
}
|
||||
|
|
|
@ -17,6 +17,11 @@
|
|||
<groupId>com.squareup.okio</groupId>
|
||||
<artifactId>okio</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>jsr305</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.lang.reflect.Type;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static com.squareup.moshi.Util.jsonAnnotations;
|
||||
|
||||
|
@ -36,7 +37,7 @@ final class AdapterMethodsFactory implements JsonAdapter.Factory {
|
|||
this.fromAdapters = fromAdapters;
|
||||
}
|
||||
|
||||
@Override public JsonAdapter<?> create(
|
||||
@Override public @Nullable JsonAdapter<?> create(
|
||||
final Type type, final Set<? extends Annotation> annotations, final Moshi moshi) {
|
||||
final AdapterMethod toAdapter = get(toAdapters, type, annotations);
|
||||
final AdapterMethod fromAdapter = get(fromAdapters, type, annotations);
|
||||
|
@ -59,7 +60,7 @@ final class AdapterMethodsFactory implements JsonAdapter.Factory {
|
|||
if (fromAdapter != null) fromAdapter.bind(moshi, this);
|
||||
|
||||
return new JsonAdapter<Object>() {
|
||||
@Override public void toJson(JsonWriter writer, Object value) throws IOException {
|
||||
@Override public void toJson(JsonWriter writer, @Nullable Object value) throws IOException {
|
||||
if (toAdapter == null) {
|
||||
delegate.toJson(writer, value);
|
||||
} else if (!toAdapter.nullable && value == null) {
|
||||
|
@ -75,7 +76,7 @@ final class AdapterMethodsFactory implements JsonAdapter.Factory {
|
|||
}
|
||||
}
|
||||
|
||||
@Override public Object fromJson(JsonReader reader) throws IOException {
|
||||
@Override public @Nullable Object fromJson(JsonReader reader) throws IOException {
|
||||
if (fromAdapter == null) {
|
||||
return delegate.fromJson(reader);
|
||||
} else if (!fromAdapter.nullable && reader.peek() == JsonReader.Token.NULL) {
|
||||
|
@ -155,7 +156,7 @@ final class AdapterMethodsFactory implements JsonAdapter.Factory {
|
|||
Set<? extends Annotation> qualifierAnnotations = jsonAnnotations(parameterAnnotations[1]);
|
||||
return new AdapterMethod(parameterTypes[1], qualifierAnnotations, adapter, method,
|
||||
parameterTypes.length, 2, true) {
|
||||
@Override public void toJson(Moshi moshi, JsonWriter writer, Object value)
|
||||
@Override public void toJson(Moshi moshi, JsonWriter writer, @Nullable Object value)
|
||||
throws IOException, InvocationTargetException {
|
||||
invoke(writer, value);
|
||||
}
|
||||
|
@ -175,7 +176,7 @@ final class AdapterMethodsFactory implements JsonAdapter.Factory {
|
|||
delegate = moshi.adapter(returnType, returnTypeAnnotations);
|
||||
}
|
||||
|
||||
@Override public void toJson(Moshi moshi, JsonWriter writer, Object value)
|
||||
@Override public void toJson(Moshi moshi, JsonWriter writer, @Nullable Object value)
|
||||
throws IOException, InvocationTargetException {
|
||||
Object intermediate = invoke(value);
|
||||
delegate.toJson(writer, intermediate);
|
||||
|
@ -260,7 +261,7 @@ final class AdapterMethodsFactory implements JsonAdapter.Factory {
|
|||
}
|
||||
|
||||
/** Returns the matching adapter method from the list. */
|
||||
private static AdapterMethod get(
|
||||
private static @Nullable AdapterMethod get(
|
||||
List<AdapterMethod> adapterMethods, Type type, Set<? extends Annotation> annotations) {
|
||||
for (int i = 0, size = adapterMethods.size(); i < size; i++) {
|
||||
AdapterMethod adapterMethod = adapterMethods.get(i);
|
||||
|
@ -306,18 +307,18 @@ final class AdapterMethodsFactory implements JsonAdapter.Factory {
|
|||
}
|
||||
}
|
||||
|
||||
public void toJson(Moshi moshi, JsonWriter writer, Object value)
|
||||
public void toJson(Moshi moshi, JsonWriter writer, @Nullable Object value)
|
||||
throws IOException, InvocationTargetException {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
public Object fromJson(Moshi moshi, JsonReader reader)
|
||||
public @Nullable Object fromJson(Moshi moshi, JsonReader reader)
|
||||
throws IOException, InvocationTargetException {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
/** Invoke the method with one fixed argument, plus any number of JSON adapter arguments. */
|
||||
protected Object invoke(Object a1) throws InvocationTargetException {
|
||||
protected @Nullable Object invoke(@Nullable Object a1) throws InvocationTargetException {
|
||||
Object[] args = new Object[1 + jsonAdapters.length];
|
||||
args[0] = a1;
|
||||
System.arraycopy(jsonAdapters, 0, args, 1, jsonAdapters.length);
|
||||
|
@ -330,7 +331,8 @@ final class AdapterMethodsFactory implements JsonAdapter.Factory {
|
|||
}
|
||||
|
||||
/** Invoke the method with two fixed arguments, plus any number of JSON adapter arguments. */
|
||||
protected Object invoke(Object a1, Object a2) throws InvocationTargetException {
|
||||
protected Object invoke(@Nullable Object a1, @Nullable Object a2)
|
||||
throws InvocationTargetException {
|
||||
Object[] args = new Object[2 + jsonAdapters.length];
|
||||
args[0] = a1;
|
||||
args[1] = a2;
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.lang.reflect.Type;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Converts arrays to JSON arrays containing their converted contents. This
|
||||
|
@ -29,7 +30,7 @@ import java.util.Set;
|
|||
*/
|
||||
final class ArrayJsonAdapter extends JsonAdapter<Object> {
|
||||
public static final Factory FACTORY = new Factory() {
|
||||
@Override public JsonAdapter<?> create(
|
||||
@Override public @Nullable JsonAdapter<?> create(
|
||||
Type type, Set<? extends Annotation> annotations, Moshi moshi) {
|
||||
Type elementType = Types.arrayComponentType(type);
|
||||
if (elementType == null) return null;
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.lang.reflect.Type;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Emits a regular class as a JSON object by mapping Java fields to JSON object properties.
|
||||
|
@ -42,7 +43,7 @@ import java.util.TreeMap;
|
|||
*/
|
||||
final class ClassJsonAdapter<T> extends JsonAdapter<T> {
|
||||
public static final JsonAdapter.Factory FACTORY = new JsonAdapter.Factory() {
|
||||
@Override public JsonAdapter<?> create(
|
||||
@Override public @Nullable JsonAdapter<?> create(
|
||||
Type type, Set<? extends Annotation> annotations, Moshi moshi) {
|
||||
Class<?> rawType = Types.getRawType(type);
|
||||
if (rawType.isInterface() || rawType.isEnum()) return null;
|
||||
|
|
|
@ -23,11 +23,12 @@ import java.util.Collection;
|
|||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/** Converts collection types to JSON arrays containing their converted contents. */
|
||||
abstract class CollectionJsonAdapter<C extends Collection<T>, T> extends JsonAdapter<C> {
|
||||
public static final JsonAdapter.Factory FACTORY = new JsonAdapter.Factory() {
|
||||
@Override public JsonAdapter<?> create(
|
||||
@Override public @Nullable JsonAdapter<?> create(
|
||||
Type type, Set<? extends Annotation> annotations, Moshi moshi) {
|
||||
Class<?> rawType = Types.getRawType(type);
|
||||
if (!annotations.isEmpty()) return null;
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.lang.annotation.Annotation;
|
|||
import java.lang.reflect.Type;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
import okio.Buffer;
|
||||
import okio.BufferedSink;
|
||||
import okio.BufferedSource;
|
||||
|
@ -28,24 +29,24 @@ import okio.BufferedSource;
|
|||
* Converts Java values to JSON, and JSON values to Java.
|
||||
*/
|
||||
public abstract class JsonAdapter<T> {
|
||||
public abstract T fromJson(JsonReader reader) throws IOException;
|
||||
public abstract @Nullable T fromJson(JsonReader reader) throws IOException;
|
||||
|
||||
public final T fromJson(BufferedSource source) throws IOException {
|
||||
public final @Nullable T fromJson(BufferedSource source) throws IOException {
|
||||
return fromJson(JsonReader.of(source));
|
||||
}
|
||||
|
||||
public final T fromJson(String string) throws IOException {
|
||||
public final @Nullable T fromJson(String string) throws IOException {
|
||||
return fromJson(new Buffer().writeUtf8(string));
|
||||
}
|
||||
|
||||
public abstract void toJson(JsonWriter writer, T value) throws IOException;
|
||||
public abstract void toJson(JsonWriter writer, @Nullable T value) throws IOException;
|
||||
|
||||
public final void toJson(BufferedSink sink, T value) throws IOException {
|
||||
public final void toJson(BufferedSink sink, @Nullable T value) throws IOException {
|
||||
JsonWriter writer = JsonWriter.of(sink);
|
||||
toJson(writer, value);
|
||||
}
|
||||
|
||||
public final String toJson(T value) {
|
||||
public final String toJson(@Nullable T value) {
|
||||
Buffer buffer = new Buffer();
|
||||
try {
|
||||
toJson(buffer, value);
|
||||
|
@ -65,7 +66,7 @@ public abstract class JsonAdapter<T> {
|
|||
* Long}), as a {@link Double} for boxed floating point types ({@link Float} and {@link Double}),
|
||||
* and as a {@link BigDecimal} for all other types.
|
||||
*/
|
||||
public final Object toJsonValue(T value) {
|
||||
public final @Nullable Object toJsonValue(@Nullable T value) {
|
||||
JsonValueWriter writer = new JsonValueWriter();
|
||||
try {
|
||||
toJson(writer, value);
|
||||
|
@ -79,7 +80,7 @@ public abstract class JsonAdapter<T> {
|
|||
* Decodes a Java value object from {@code value}, which must be comprised of maps, lists,
|
||||
* strings, numbers, booleans and nulls.
|
||||
*/
|
||||
public final T fromJsonValue(Object value) {
|
||||
public final @Nullable T fromJsonValue(@Nullable Object value) {
|
||||
JsonValueReader reader = new JsonValueReader(value);
|
||||
try {
|
||||
return fromJson(reader);
|
||||
|
@ -95,10 +96,10 @@ public abstract class JsonAdapter<T> {
|
|||
public final JsonAdapter<T> serializeNulls() {
|
||||
final JsonAdapter<T> delegate = this;
|
||||
return new JsonAdapter<T>() {
|
||||
@Override public T fromJson(JsonReader reader) throws IOException {
|
||||
@Override public @Nullable T fromJson(JsonReader reader) throws IOException {
|
||||
return delegate.fromJson(reader);
|
||||
}
|
||||
@Override public void toJson(JsonWriter writer, T value) throws IOException {
|
||||
@Override public void toJson(JsonWriter writer, @Nullable T value) throws IOException {
|
||||
boolean serializeNulls = writer.getSerializeNulls();
|
||||
writer.setSerializeNulls(true);
|
||||
try {
|
||||
|
@ -120,14 +121,14 @@ public abstract class JsonAdapter<T> {
|
|||
public final JsonAdapter<T> nullSafe() {
|
||||
final JsonAdapter<T> delegate = this;
|
||||
return new JsonAdapter<T>() {
|
||||
@Override public T fromJson(JsonReader reader) throws IOException {
|
||||
@Override public @Nullable T fromJson(JsonReader reader) throws IOException {
|
||||
if (reader.peek() == JsonReader.Token.NULL) {
|
||||
return reader.nextNull();
|
||||
} else {
|
||||
return delegate.fromJson(reader);
|
||||
}
|
||||
}
|
||||
@Override public void toJson(JsonWriter writer, T value) throws IOException {
|
||||
@Override public void toJson(JsonWriter writer, @Nullable T value) throws IOException {
|
||||
if (value == null) {
|
||||
writer.nullValue();
|
||||
} else {
|
||||
|
@ -144,7 +145,7 @@ public abstract class JsonAdapter<T> {
|
|||
public final JsonAdapter<T> lenient() {
|
||||
final JsonAdapter<T> delegate = this;
|
||||
return new JsonAdapter<T>() {
|
||||
@Override public T fromJson(JsonReader reader) throws IOException {
|
||||
@Override public @Nullable T fromJson(JsonReader reader) throws IOException {
|
||||
boolean lenient = reader.isLenient();
|
||||
reader.setLenient(true);
|
||||
try {
|
||||
|
@ -153,7 +154,7 @@ public abstract class JsonAdapter<T> {
|
|||
reader.setLenient(lenient);
|
||||
}
|
||||
}
|
||||
@Override public void toJson(JsonWriter writer, T value) throws IOException {
|
||||
@Override public void toJson(JsonWriter writer, @Nullable T value) throws IOException {
|
||||
boolean lenient = writer.isLenient();
|
||||
writer.setLenient(true);
|
||||
try {
|
||||
|
@ -177,7 +178,7 @@ public abstract class JsonAdapter<T> {
|
|||
public final JsonAdapter<T> failOnUnknown() {
|
||||
final JsonAdapter<T> delegate = this;
|
||||
return new JsonAdapter<T>() {
|
||||
@Override public T fromJson(JsonReader reader) throws IOException {
|
||||
@Override public @Nullable T fromJson(JsonReader reader) throws IOException {
|
||||
boolean skipForbidden = reader.failOnUnknown();
|
||||
reader.setFailOnUnknown(true);
|
||||
try {
|
||||
|
@ -186,7 +187,7 @@ public abstract class JsonAdapter<T> {
|
|||
reader.setFailOnUnknown(skipForbidden);
|
||||
}
|
||||
}
|
||||
@Override public void toJson(JsonWriter writer, T value) throws IOException {
|
||||
@Override public void toJson(JsonWriter writer, @Nullable T value) throws IOException {
|
||||
delegate.toJson(writer, value);
|
||||
}
|
||||
@Override public String toString() {
|
||||
|
@ -209,10 +210,10 @@ public abstract class JsonAdapter<T> {
|
|||
}
|
||||
final JsonAdapter<T> delegate = this;
|
||||
return new JsonAdapter<T>() {
|
||||
@Override public T fromJson(JsonReader reader) throws IOException {
|
||||
@Override public @Nullable T fromJson(JsonReader reader) throws IOException {
|
||||
return delegate.fromJson(reader);
|
||||
}
|
||||
@Override public void toJson(JsonWriter writer, T value) throws IOException {
|
||||
@Override public void toJson(JsonWriter writer, @Nullable T value) throws IOException {
|
||||
String originalIndent = writer.getIndent();
|
||||
writer.setIndent(indent);
|
||||
try {
|
||||
|
@ -236,6 +237,6 @@ public abstract class JsonAdapter<T> {
|
|||
* <p>Implementations may use to {@link Moshi#adapter} to compose adapters of other types, or
|
||||
* {@link Moshi#nextAdapter} to delegate to the underlying adapter of the same type.
|
||||
*/
|
||||
JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations, Moshi moshi);
|
||||
@Nullable JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations, Moshi moshi);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package com.squareup.moshi;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Thrown when the data in a JSON document doesn't match the data expected by the caller. For
|
||||
* example, suppose the application expects a boolean but the JSON document contains a string. When
|
||||
|
@ -31,15 +33,15 @@ public final class JsonDataException extends RuntimeException {
|
|||
public JsonDataException() {
|
||||
}
|
||||
|
||||
public JsonDataException(String message) {
|
||||
public JsonDataException(@Nullable String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public JsonDataException(Throwable cause) {
|
||||
public JsonDataException(@Nullable Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public JsonDataException(String message, Throwable cause) {
|
||||
public JsonDataException(@Nullable String message, @Nullable Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,10 +16,11 @@
|
|||
package com.squareup.moshi;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/** Thrown when the data being parsed is not encoded as valid JSON. */
|
||||
public final class JsonEncodingException extends IOException {
|
||||
public JsonEncodingException(String message) {
|
||||
public JsonEncodingException(@Nullable String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.io.IOException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
import okio.Buffer;
|
||||
import okio.BufferedSource;
|
||||
import okio.ByteString;
|
||||
|
@ -212,7 +213,7 @@ public abstract class JsonReader implements Closeable {
|
|||
throw new JsonEncodingException(message + " at path " + getPath());
|
||||
}
|
||||
|
||||
final JsonDataException typeMismatch(Object value, Object expected) {
|
||||
final JsonDataException typeMismatch(@Nullable Object value, Object expected) {
|
||||
if (value == null) {
|
||||
return new JsonDataException(
|
||||
"Expected " + expected + " but was null at path " + getPath());
|
||||
|
@ -351,7 +352,7 @@ public abstract class JsonReader implements Closeable {
|
|||
*
|
||||
* @throws JsonDataException if the next token is not null or if this reader is closed.
|
||||
*/
|
||||
public abstract <T> T nextNull() throws IOException;
|
||||
public abstract @Nullable <T> T nextNull() throws IOException;
|
||||
|
||||
/**
|
||||
* Returns the {@linkplain Token#NUMBER double} value of the next token, consuming it. If the next
|
||||
|
@ -400,7 +401,7 @@ public abstract class JsonReader implements Closeable {
|
|||
* @throws JsonDataException if the next token is not a literal value, if a JSON object has a
|
||||
* duplicate key.
|
||||
*/
|
||||
public final Object readJsonValue() throws IOException {
|
||||
public final @Nullable Object readJsonValue() throws IOException {
|
||||
switch (peek()) {
|
||||
case BEGIN_ARRAY:
|
||||
List<Object> list = new ArrayList<>();
|
||||
|
|
|
@ -18,6 +18,7 @@ package com.squareup.moshi;
|
|||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import javax.annotation.Nullable;
|
||||
import okio.Buffer;
|
||||
import okio.BufferedSource;
|
||||
import okio.ByteString;
|
||||
|
@ -86,7 +87,7 @@ final class JsonUtf8Reader extends JsonReader {
|
|||
* This is populated before a numeric value is parsed and used if that parsing
|
||||
* fails.
|
||||
*/
|
||||
private String peekedString;
|
||||
private @Nullable String peekedString;
|
||||
|
||||
JsonUtf8Reader(BufferedSource source) {
|
||||
if (source == null) {
|
||||
|
@ -670,7 +671,7 @@ final class JsonUtf8Reader extends JsonReader {
|
|||
throw new JsonDataException("Expected a boolean but was " + peek() + " at path " + getPath());
|
||||
}
|
||||
|
||||
@Override public <T> T nextNull() throws IOException {
|
||||
@Override public @Nullable <T> T nextNull() throws IOException {
|
||||
int p = peeked;
|
||||
if (p == PEEKED_NONE) {
|
||||
p = doPeek();
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package com.squareup.moshi;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.annotation.Nullable;
|
||||
import okio.BufferedSink;
|
||||
import okio.Sink;
|
||||
|
||||
|
@ -222,7 +223,7 @@ final class JsonUtf8Writer extends JsonWriter {
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override public JsonWriter value(Number value) throws IOException {
|
||||
@Override public JsonWriter value(@Nullable Number value) throws IOException {
|
||||
if (value == null) {
|
||||
return nullValue();
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.util.Iterator;
|
|||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* This class reads a JSON document by traversing a Java object comprising maps, lists, and JSON
|
||||
|
@ -173,7 +174,7 @@ final class JsonValueReader extends JsonReader {
|
|||
return peeked;
|
||||
}
|
||||
|
||||
@Override public <T> T nextNull() throws IOException {
|
||||
@Override public @Nullable <T> T nextNull() throws IOException {
|
||||
require(Void.class, Token.NULL);
|
||||
remove();
|
||||
return null;
|
||||
|
@ -297,7 +298,7 @@ final class JsonValueReader extends JsonReader {
|
|||
* Returns the top of the stack which is required to be a {@code type}. Throws if this reader is
|
||||
* closed, or if the type isn't what was expected.
|
||||
*/
|
||||
private <T> T require(Class<T> type, Token expected) throws IOException {
|
||||
private @Nullable <T> T require(Class<T> type, Token expected) throws IOException {
|
||||
Object peeked = (stackSize != 0 ? stack[stackSize - 1] : null);
|
||||
|
||||
if (type.isInstance(peeked)) {
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.math.BigDecimal;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static com.squareup.moshi.JsonScope.EMPTY_ARRAY;
|
||||
import static com.squareup.moshi.JsonScope.EMPTY_DOCUMENT;
|
||||
|
@ -31,7 +32,7 @@ import static java.lang.Double.POSITIVE_INFINITY;
|
|||
/** Writes JSON by building a Java object comprising maps, lists, and JSON primitives. */
|
||||
final class JsonValueWriter extends JsonWriter {
|
||||
private final Object[] stack = new Object[32];
|
||||
private String deferredName;
|
||||
private @Nullable String deferredName;
|
||||
|
||||
JsonValueWriter() {
|
||||
pushScope(EMPTY_DOCUMENT);
|
||||
|
@ -106,7 +107,7 @@ final class JsonValueWriter extends JsonWriter {
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override public JsonWriter value(String value) throws IOException {
|
||||
@Override public JsonWriter value(@Nullable String value) throws IOException {
|
||||
if (promoteValueToName) {
|
||||
return name(value);
|
||||
}
|
||||
|
@ -127,7 +128,7 @@ final class JsonValueWriter extends JsonWriter {
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override public JsonWriter value(Boolean value) throws IOException {
|
||||
@Override public JsonWriter value(@Nullable Boolean value) throws IOException {
|
||||
add(value);
|
||||
pathIndices[stackSize - 1]++;
|
||||
return this;
|
||||
|
@ -155,7 +156,7 @@ final class JsonValueWriter extends JsonWriter {
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override public JsonWriter value(Number value) throws IOException {
|
||||
@Override public JsonWriter value(@Nullable Number value) throws IOException {
|
||||
// If it's trivially converted to a long, do that.
|
||||
if (value instanceof Byte
|
||||
|| value instanceof Short
|
||||
|
@ -169,6 +170,10 @@ final class JsonValueWriter extends JsonWriter {
|
|||
return value(value.doubleValue());
|
||||
}
|
||||
|
||||
if (value == null) {
|
||||
return nullValue();
|
||||
}
|
||||
|
||||
// Everything else gets converted to a BigDecimal.
|
||||
BigDecimal bigDecimalValue = value instanceof BigDecimal
|
||||
? ((BigDecimal) value)
|
||||
|
@ -195,7 +200,7 @@ final class JsonValueWriter extends JsonWriter {
|
|||
}
|
||||
}
|
||||
|
||||
private JsonValueWriter add(Object newTop) {
|
||||
private JsonValueWriter add(@Nullable Object newTop) {
|
||||
int scope = peekScope();
|
||||
|
||||
if (stackSize == 1) {
|
||||
|
|
|
@ -18,6 +18,7 @@ package com.squareup.moshi;
|
|||
import java.io.Closeable;
|
||||
import java.io.Flushable;
|
||||
import java.io.IOException;
|
||||
import javax.annotation.Nullable;
|
||||
import okio.BufferedSink;
|
||||
|
||||
import static com.squareup.moshi.JsonScope.EMPTY_OBJECT;
|
||||
|
@ -257,7 +258,7 @@ public abstract class JsonWriter implements Closeable, Flushable {
|
|||
/**
|
||||
* Encodes the property name.
|
||||
*
|
||||
* @param name the name of the forthcoming value. May not be null.
|
||||
* @param name the name of the forthcoming value. Must not be null.
|
||||
* @return this writer.
|
||||
*/
|
||||
public abstract JsonWriter name(String name) throws IOException;
|
||||
|
@ -268,7 +269,7 @@ public abstract class JsonWriter implements Closeable, Flushable {
|
|||
* @param value the literal string value, or null to encode a null literal.
|
||||
* @return this writer.
|
||||
*/
|
||||
public abstract JsonWriter value(String value) throws IOException;
|
||||
public abstract JsonWriter value(@Nullable String value) throws IOException;
|
||||
|
||||
/**
|
||||
* Encodes {@code null}.
|
||||
|
@ -289,7 +290,7 @@ public abstract class JsonWriter implements Closeable, Flushable {
|
|||
*
|
||||
* @return this writer.
|
||||
*/
|
||||
public abstract JsonWriter value(Boolean value) throws IOException;
|
||||
public abstract JsonWriter value(@Nullable Boolean value) throws IOException;
|
||||
|
||||
/**
|
||||
* Encodes {@code value}.
|
||||
|
@ -314,7 +315,7 @@ public abstract class JsonWriter implements Closeable, Flushable {
|
|||
* {@linkplain Double#isInfinite() infinities}.
|
||||
* @return this writer.
|
||||
*/
|
||||
public abstract JsonWriter value(Number value) throws IOException;
|
||||
public abstract JsonWriter value(@Nullable Number value) throws IOException;
|
||||
|
||||
/**
|
||||
* Changes the writer to treat the next value as a string name. This is useful for map adapters so
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.lang.annotation.Annotation;
|
|||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Converts maps with string keys to JSON objects.
|
||||
|
@ -28,7 +29,7 @@ import java.util.Set;
|
|||
*/
|
||||
final class MapJsonAdapter<K, V> extends JsonAdapter<Map<K, V>> {
|
||||
public static final Factory FACTORY = new Factory() {
|
||||
@Override public JsonAdapter<?> create(
|
||||
@Override public @Nullable JsonAdapter<?> create(
|
||||
Type type, Set<? extends Annotation> annotations, Moshi moshi) {
|
||||
if (!annotations.isEmpty()) return null;
|
||||
Class<?> rawType = Types.getRawType(type);
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.util.LinkedHashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Coordinates binding between JSON values and Java objects.
|
||||
|
@ -154,7 +155,7 @@ public final class Moshi {
|
|||
if (jsonAdapter == null) throw new IllegalArgumentException("jsonAdapter == null");
|
||||
|
||||
return add(new JsonAdapter.Factory() {
|
||||
@Override public JsonAdapter<?> create(
|
||||
@Override public @Nullable JsonAdapter<?> create(
|
||||
Type targetType, Set<? extends Annotation> annotations, Moshi moshi) {
|
||||
return annotations.isEmpty() && Util.typesMatch(type, targetType) ? jsonAdapter : null;
|
||||
}
|
||||
|
@ -174,7 +175,7 @@ public final class Moshi {
|
|||
}
|
||||
|
||||
return add(new JsonAdapter.Factory() {
|
||||
@Override public JsonAdapter<?> create(
|
||||
@Override public @Nullable JsonAdapter<?> create(
|
||||
Type targetType, Set<? extends Annotation> annotations, Moshi moshi) {
|
||||
if (Util.typesMatch(type, targetType)
|
||||
&& annotations.size() == 1
|
||||
|
@ -216,8 +217,8 @@ public final class Moshi {
|
|||
* class that has a {@code List<Employee>} field for an organization's management hierarchy.
|
||||
*/
|
||||
private static class DeferredAdapter<T> extends JsonAdapter<T> {
|
||||
Object cacheKey;
|
||||
private JsonAdapter<T> delegate;
|
||||
@Nullable Object cacheKey;
|
||||
private @Nullable JsonAdapter<T> delegate;
|
||||
|
||||
DeferredAdapter(Object cacheKey) {
|
||||
this.cacheKey = cacheKey;
|
||||
|
|
|
@ -34,6 +34,7 @@ import java.util.Map;
|
|||
import java.util.NoSuchElementException;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/** Factory methods for types. */
|
||||
public final class Types {
|
||||
|
@ -200,12 +201,12 @@ public final class Types {
|
|||
});
|
||||
}
|
||||
|
||||
static boolean equal(Object a, Object b) {
|
||||
static boolean equal(@Nullable Object a, @Nullable Object b) {
|
||||
return a == b || (a != null && a.equals(b));
|
||||
}
|
||||
|
||||
/** Returns true if {@code a} and {@code b} are equal. */
|
||||
public static boolean equals(Type a, Type b) {
|
||||
public static boolean equals(@Nullable Type a, @Nullable Type b) {
|
||||
if (a == b) {
|
||||
return true; // Also handles (a == null && b == null).
|
||||
|
||||
|
@ -260,7 +261,7 @@ public final class Types {
|
|||
}
|
||||
}
|
||||
|
||||
static int hashCodeOrZero(Object o) {
|
||||
static int hashCodeOrZero(@Nullable Object o) {
|
||||
return o != null ? o.hashCode() : 0;
|
||||
}
|
||||
|
||||
|
@ -484,7 +485,7 @@ public final class Types {
|
|||
* Returns the declaring class of {@code typeVariable}, or {@code null} if it was not declared by
|
||||
* a class.
|
||||
*/
|
||||
private static Class<?> declaringClassOf(TypeVariable<?> typeVariable) {
|
||||
private static @Nullable Class<?> declaringClassOf(TypeVariable<?> typeVariable) {
|
||||
GenericDeclaration genericDeclaration = typeVariable.getGenericDeclaration();
|
||||
return genericDeclaration instanceof Class ? (Class<?>) genericDeclaration : null;
|
||||
}
|
||||
|
@ -496,11 +497,11 @@ public final class Types {
|
|||
}
|
||||
|
||||
private static final class ParameterizedTypeImpl implements ParameterizedType {
|
||||
private final Type ownerType;
|
||||
private final @Nullable Type ownerType;
|
||||
private final Type rawType;
|
||||
final Type[] typeArguments;
|
||||
|
||||
ParameterizedTypeImpl(Type ownerType, Type rawType, Type... typeArguments) {
|
||||
ParameterizedTypeImpl(@Nullable Type ownerType, Type rawType, Type... typeArguments) {
|
||||
// Require an owner type if the raw type needs it.
|
||||
if (rawType instanceof Class<?>
|
||||
&& (ownerType == null) != (((Class<?>) rawType).getEnclosingClass() == null)) {
|
||||
|
@ -526,7 +527,7 @@ public final class Types {
|
|||
return rawType;
|
||||
}
|
||||
|
||||
@Override public Type getOwnerType() {
|
||||
@Override public @Nullable Type getOwnerType() {
|
||||
return ownerType;
|
||||
}
|
||||
|
||||
|
@ -589,7 +590,7 @@ public final class Types {
|
|||
*/
|
||||
private static final class WildcardTypeImpl implements WildcardType {
|
||||
private final Type upperBound;
|
||||
private final Type lowerBound;
|
||||
private final @Nullable Type lowerBound;
|
||||
|
||||
WildcardTypeImpl(Type[] upperBounds, Type[] lowerBounds) {
|
||||
if (lowerBounds.length > 1) throw new IllegalArgumentException();
|
||||
|
|
3
moshi/src/main/java/com/squareup/moshi/package-info.java
Normal file
3
moshi/src/main/java/com/squareup/moshi/package-info.java
Normal file
|
@ -0,0 +1,3 @@
|
|||
/** Moshi is modern JSON library for Android and Java. */
|
||||
@javax.annotation.ParametersAreNonnullByDefault
|
||||
package com.squareup.moshi;
|
|
@ -286,6 +286,15 @@ public final class JsonWriterTest {
|
|||
+ "3.141592653589793238462643383]");
|
||||
}
|
||||
|
||||
@Test public void nullNumbers() throws IOException {
|
||||
JsonWriter writer = factory.newWriter();
|
||||
writer.beginArray();
|
||||
writer.value((Number) null);
|
||||
writer.endArray();
|
||||
writer.close();
|
||||
assertThat(factory.json()).isEqualTo("[null]");
|
||||
}
|
||||
|
||||
@Test public void booleans() throws IOException {
|
||||
JsonWriter writer = factory.newWriter();
|
||||
writer.beginArray();
|
||||
|
|
6
pom.xml
6
pom.xml
|
@ -58,6 +58,12 @@
|
|||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>jsr305</artifactId>
|
||||
<version>3.0.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
|
|
Loading…
Reference in a new issue