diff --git a/moshi/src/main/java/com/squareup/moshi/AdapterMethodsFactory.java b/moshi/src/main/java/com/squareup/moshi/AdapterMethodsFactory.java index b61a56b..94690b5 100644 --- a/moshi/src/main/java/com/squareup/moshi/AdapterMethodsFactory.java +++ b/moshi/src/main/java/com/squareup/moshi/AdapterMethodsFactory.java @@ -55,8 +55,8 @@ final class AdapterMethodsFactory implements JsonAdapter.Factory { delegate = null; } - if (toAdapter != null) toAdapter.bind(moshi); - if (fromAdapter != null) fromAdapter.bind(moshi); + if (toAdapter != null) toAdapter.bind(moshi, this); + if (fromAdapter != null) fromAdapter.bind(moshi, this); return new JsonAdapter() { @Override public void toJson(JsonWriter writer, Object value) throws IOException { @@ -170,8 +170,8 @@ final class AdapterMethodsFactory implements JsonAdapter.Factory { parameterTypes.length, 1, nullable) { private JsonAdapter delegate; - @Override public void bind(Moshi moshi) { - super.bind(moshi); + @Override public void bind(Moshi moshi, JsonAdapter.Factory factory) { + super.bind(moshi, factory); delegate = moshi.adapter(returnType, returnTypeAnnotations); } @@ -235,8 +235,8 @@ final class AdapterMethodsFactory implements JsonAdapter.Factory { parameterTypes.length, 1, nullable) { JsonAdapter delegate; - @Override public void bind(Moshi moshi) { - super.bind(moshi); + @Override public void bind(Moshi moshi, JsonAdapter.Factory factory) { + super.bind(moshi, factory); delegate = moshi.adapter(parameterTypes[0], qualifierAnnotations); } @@ -289,14 +289,17 @@ final class AdapterMethodsFactory implements JsonAdapter.Factory { this.nullable = nullable; } - public void bind(Moshi moshi) { + public void bind(Moshi moshi, JsonAdapter.Factory factory) { if (jsonAdapters.length > 0) { Type[] parameterTypes = method.getGenericParameterTypes(); Annotation[][] parameterAnnotations = method.getParameterAnnotations(); for (int i = adaptersOffset, size = parameterTypes.length; i < size; i++) { - jsonAdapters[i - adaptersOffset] = moshi.adapter( - ((ParameterizedType) parameterTypes[i]).getActualTypeArguments()[0], - jsonAnnotations(parameterAnnotations[i])); + Type type = ((ParameterizedType) parameterTypes[i]).getActualTypeArguments()[0]; + Set jsonAnnotations = jsonAnnotations(parameterAnnotations[i]); + jsonAdapters[i - adaptersOffset] = + Types.equals(this.type, type) && annotations.equals(jsonAnnotations) + ? moshi.nextAdapter(factory, type, jsonAnnotations) + : moshi.adapter(type, jsonAnnotations); } } } diff --git a/moshi/src/test/java/com/squareup/moshi/AdapterMethodsTest.java b/moshi/src/test/java/com/squareup/moshi/AdapterMethodsTest.java index 83fa9fb..3e52f34 100644 --- a/moshi/src/test/java/com/squareup/moshi/AdapterMethodsTest.java +++ b/moshi/src/test/java/com/squareup/moshi/AdapterMethodsTest.java @@ -79,6 +79,55 @@ public final class AdapterMethodsTest { } } + private static final class PointJsonAdapterWithDelegate { + @FromJson Point fromJson(JsonReader reader, JsonAdapter delegate) throws IOException { + reader.beginArray(); + Point value = delegate.fromJson(reader); + reader.endArray(); + return value; + } + + @ToJson void toJson(JsonWriter writer, Point value, JsonAdapter delegate) + throws IOException { + writer.beginArray(); + delegate.toJson(writer, value); + writer.endArray(); + } + } + + private static final class PointJsonAdapterWithDelegateWithQualifier { + @FromJson @WithParens Point fromJson(JsonReader reader, JsonAdapter delegate) + throws IOException { + reader.beginArray(); + Point value = delegate.fromJson(reader); + reader.endArray(); + return value; + } + + @ToJson void toJson(JsonWriter writer, @WithParens Point value, JsonAdapter delegate) + throws IOException { + writer.beginArray(); + delegate.toJson(writer, value); + writer.endArray(); + } + } + + @Test public void toAndFromWithDelegate() throws Exception { + Moshi moshi = new Moshi.Builder().add(new PointJsonAdapterWithDelegate()).build(); + JsonAdapter adapter = moshi.adapter(Point.class); + Point point = new Point(5, 8); + assertThat(adapter.toJson(point)).isEqualTo("[{\"x\":5,\"y\":8}]"); + assertThat(adapter.fromJson("[{\"x\":5,\"y\":8}]")).isEqualTo(point); + } + + @Test public void toAndFromWithDelegateWithQualifier() throws Exception { + Moshi moshi = new Moshi.Builder().add(new PointJsonAdapterWithDelegateWithQualifier()).build(); + JsonAdapter adapter = moshi.adapter(Point.class, WithParens.class); + Point point = new Point(5, 8); + assertThat(adapter.toJson(point)).isEqualTo("[{\"x\":5,\"y\":8}]"); + assertThat(adapter.fromJson("[{\"x\":5,\"y\":8}]")).isEqualTo(point); + } + @Test public void toJsonOnly() throws Exception { Moshi moshi = new Moshi.Builder() .add(new PointAsListOfIntegersToAdapter()) @@ -308,7 +357,7 @@ public final class AdapterMethodsTest { } static class NullableIntToJsonAdapter { - @FromJson int intToJson(JsonReader reader) throws IOException { + @FromJson int jsonToInt(JsonReader reader) throws IOException { if (reader.peek() == JsonReader.Token.NULL) { reader.nextNull(); return -1; @@ -316,7 +365,7 @@ public final class AdapterMethodsTest { return reader.nextInt(); } - @ToJson void jsonToInt(JsonWriter writer, int value) throws IOException { + @ToJson void intToJson(JsonWriter writer, int value) throws IOException { if (value == -1) { writer.nullValue(); } else {