From 8e28dd4ad74e7ad9eec1889bcc2963df745456bc Mon Sep 17 00:00:00 2001 From: Eric Cochran Date: Sat, 24 Feb 2018 01:46:42 -0800 Subject: [PATCH] Fail earlier for some incorrect owner types. (#450) --- moshi/src/main/java/com/squareup/moshi/Types.java | 15 +++++++++++---- .../test/java/com/squareup/moshi/TypesTest.java | 12 ++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/moshi/src/main/java/com/squareup/moshi/Types.java b/moshi/src/main/java/com/squareup/moshi/Types.java index 0b07880..80459d1 100644 --- a/moshi/src/main/java/com/squareup/moshi/Types.java +++ b/moshi/src/main/java/com/squareup/moshi/Types.java @@ -503,10 +503,17 @@ public final class Types { 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)) { - throw new IllegalArgumentException( - "unexpected owner type for " + rawType + ": " + ownerType); + if (rawType instanceof Class) { + Class enclosingClass = ((Class) rawType).getEnclosingClass(); + if (ownerType != null) { + if (enclosingClass == null || Types.getRawType(ownerType) != enclosingClass) { + throw new IllegalArgumentException( + "unexpected owner type for " + rawType + ": " + ownerType); + } + } else if (enclosingClass != null) { + throw new IllegalArgumentException( + "unexpected owner type for " + rawType + ": null"); + } } this.ownerType = ownerType == null ? null : canonicalize(ownerType); diff --git a/moshi/src/test/java/com/squareup/moshi/TypesTest.java b/moshi/src/test/java/com/squareup/moshi/TypesTest.java index 2f7b74d..888ff1e 100644 --- a/moshi/src/test/java/com/squareup/moshi/TypesTest.java +++ b/moshi/src/test/java/com/squareup/moshi/TypesTest.java @@ -100,6 +100,15 @@ public final class TypesTest { } } + @Test public void parameterizedTypeWithIncorrectOwnerProvided() throws Exception { + try { + Types.newParameterizedTypeWithOwner(A.class, D.class, B.class); + fail(); + } catch (IllegalArgumentException expected) { + assertThat(expected).hasMessage("unexpected owner type for " + D.class + ": " + A.class); + } + } + @Test public void arrayOf() { assertThat(Types.getRawType(Types.arrayOf(int.class))).isEqualTo(int[].class); assertThat(Types.getRawType(Types.arrayOf(List.class))).isEqualTo(List[].class); @@ -153,6 +162,9 @@ public final class TypesTest { private static final class C { } + private static final class D { + } + /** * Given a parameterized type {@code A}, returns B. If the specified type is not a generic * type, returns null.