Full JsonQualifier support in kotlin codegen.

This commit is contained in:
Zac Sweers
2018-04-29 15:54:45 -07:00
committed by Jesse Wilson
parent 10a5dc827b
commit 4b610329bd
7 changed files with 177 additions and 26 deletions

View File

@@ -20,6 +20,7 @@ import com.squareup.moshi.internal.Util.ParameterizedTypeImpl;
import com.squareup.moshi.internal.Util.WildcardTypeImpl;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
@@ -216,6 +217,36 @@ public final class Types {
}
}
/**
* @param clazz the target class to read the {@code fieldName} field annotations from.
* @param fieldName the target field name on {@code clazz}.
* @return a set of {@link JsonQualifier}-annotated {@link Annotation} instances retrieved from
* the targeted field. Can be empty if none are found.
*/
public static Set<? extends Annotation> getFieldJsonQualifierAnnotations(Class<?> clazz,
String fieldName) {
try {
Field field = clazz.getDeclaredField(fieldName);
if (!field.isAccessible()) {
field.setAccessible(true);
}
Annotation[] fieldAnnotations = field.getDeclaredAnnotations();
Set<Annotation> annotations = new LinkedHashSet<>(fieldAnnotations.length);
for (Annotation annotation : fieldAnnotations) {
if (annotation.annotationType().isAnnotationPresent(JsonQualifier.class)) {
annotations.add(annotation);
}
}
return Collections.unmodifiableSet(annotations);
} catch (NoSuchFieldException e) {
throw new IllegalArgumentException("Could not access field "
+ fieldName
+ " on class "
+ clazz.getCanonicalName(),
e);
}
}
@SuppressWarnings("unchecked")
static <T extends Annotation> T createJsonQualifierImplementation(final Class<T> annotationType) {
if (!annotationType.isAnnotation()) {

View File

@@ -17,6 +17,7 @@ package com.squareup.moshi;
import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
@@ -29,6 +30,7 @@ import java.util.Set;
import org.junit.Test;
import static com.squareup.moshi.internal.Util.canonicalize;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
@@ -261,4 +263,52 @@ public final class TypesTest {
assertThat(expected).hasMessage("Unexpected primitive boolean. Use the boxed type.");
}
}
@Test public void getFieldJsonQualifierAnnotations_privateFieldTest() {
Set<? extends Annotation> annotations = Types.getFieldJsonQualifierAnnotations(ClassWithAnnotatedFields.class,
"privateField");
assertThat(annotations).hasSize(1);
assertThat(annotations.iterator().next()).isInstanceOf(FieldAnnotation.class);
}
@Test public void getFieldJsonQualifierAnnotations_publicFieldTest() {
Set<? extends Annotation> annotations = Types.getFieldJsonQualifierAnnotations(ClassWithAnnotatedFields.class,
"publicField");
assertThat(annotations).hasSize(1);
assertThat(annotations.iterator().next()).isInstanceOf(FieldAnnotation.class);
}
@Test public void getFieldJsonQualifierAnnotations_unannotatedTest() {
Set<? extends Annotation> annotations = Types.getFieldJsonQualifierAnnotations(ClassWithAnnotatedFields.class,
"unannotatedField");
assertThat(annotations).hasSize(0);
}
@JsonQualifier
@Target(FIELD)
@Retention(RUNTIME)
@interface FieldAnnotation {
}
@Target(FIELD)
@Retention(RUNTIME)
@interface NoQualifierAnnotation {
}
static class ClassWithAnnotatedFields {
@FieldAnnotation
@NoQualifierAnnotation
private final int privateField = 0;
@FieldAnnotation
@NoQualifierAnnotation
public final int publicField = 0;
private final int unannotatedField = 0;
}
}