Skip to content

Commit

Permalink
Merge branch 'master' into marcono1234/api-compatibility-workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
Marcono1234 committed Aug 27, 2022
2 parents f3a6e3f + f7a164d commit 3583373
Show file tree
Hide file tree
Showing 33 changed files with 251 additions and 170 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
* Writes a graph of objects as a list of named nodes.
*/
// TODO: proper documentation
@SuppressWarnings("rawtypes")
public final class GraphAdapterBuilder {
private final Map<Type, InstanceCreator<?>> instanceCreators;
private final ConstructorConstructor constructorConstructor;
Expand Down Expand Up @@ -78,7 +77,7 @@ public void registerOn(GsonBuilder gsonBuilder) {
}
}

static class Factory implements TypeAdapterFactory, InstanceCreator {
static class Factory implements TypeAdapterFactory, InstanceCreator<Object> {
private final Map<Type, InstanceCreator<?>> instanceCreators;
private final ThreadLocal<Graph> graphThreadLocal = new ThreadLocal<>();

Expand Down Expand Up @@ -215,7 +214,6 @@ public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
* <p>Gson should only ever call this method when we're expecting it to;
* that is only when we've called back into Gson to deserialize a tree.
*/
@SuppressWarnings("unchecked")
@Override
public Object createInstance(Type type) {
Graph graph = graphThreadLocal.get();
Expand All @@ -242,14 +240,14 @@ static class Graph {
* The queue of elements to write during serialization. Unused during
* deserialization.
*/
private final Queue<Element> queue = new LinkedList<>();
private final Queue<Element<?>> queue = new LinkedList<>();

/**
* The instance currently being deserialized. Used as a backdoor between
* the graph traversal (which needs to know instances) and instance creators
* which create them.
*/
private Element nextCreate;
private Element<Object> nextCreate;

private Graph(Map<Object, Element<?>> map) {
this.map = map;
Expand Down Expand Up @@ -299,11 +297,12 @@ void write(JsonWriter out) throws IOException {
typeAdapter.write(out, value);
}

@SuppressWarnings("unchecked")
void read(Graph graph) throws IOException {
if (graph.nextCreate != null) {
throw new IllegalStateException("Unexpected recursive call to read() for " + id);
}
graph.nextCreate = this;
graph.nextCreate = (Element<Object>) this;
value = typeAdapter.fromJsonTree(element);
if (value == null) {
throw new IllegalStateException("non-null value deserialized to null: " + element);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,12 @@

package com.google.gson.typeadapters;

import javax.annotation.PostConstruct;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import junit.framework.TestCase;

import java.util.Arrays;
import java.util.List;
import javax.annotation.PostConstruct;
import junit.framework.TestCase;

public class PostConstructAdapterFactoryTest extends TestCase {
public void test() throws Exception {
Expand Down Expand Up @@ -55,6 +52,7 @@ public void testList() {
assertEquals(sandwiches, sandwichesFromJson);
}

@SuppressWarnings("overrides") // for missing hashCode() override
static class Sandwich {
public String bread;
public String cheese;
Expand Down Expand Up @@ -89,6 +87,7 @@ public boolean equals(Object o) {
}
}

@SuppressWarnings("overrides") // for missing hashCode() override
static class MultipleSandwiches {
public List<Sandwich> sandwiches;

Expand Down
19 changes: 11 additions & 8 deletions gson/src/main/java/com/google/gson/Gson.java
Original file line number Diff line number Diff line change
Expand Up @@ -503,12 +503,13 @@ private static TypeAdapter<AtomicLongArray> atomicLongArrayAdapter(final TypeAda
* @throws IllegalArgumentException if this GSON cannot serialize and
* deserialize {@code type}.
*/
@SuppressWarnings("unchecked")
public <T> TypeAdapter<T> getAdapter(TypeToken<T> type) {
Objects.requireNonNull(type, "type must not be null");
TypeAdapter<?> cached = typeTokenCache.get(type);
if (cached != null) {
return (TypeAdapter<T>) cached;
@SuppressWarnings("unchecked")
TypeAdapter<T> adapter = (TypeAdapter<T>) cached;
return adapter;
}

Map<TypeToken<?>, FutureTypeAdapter<?>> threadCalls = calls.get();
Expand All @@ -520,6 +521,7 @@ public <T> TypeAdapter<T> getAdapter(TypeToken<T> type) {
}

// the key and value type parameters always agree
@SuppressWarnings("unchecked")
FutureTypeAdapter<T> ongoingCall = (FutureTypeAdapter<T>) threadCalls.get(type);
if (ongoingCall != null) {
return ongoingCall;
Expand All @@ -532,6 +534,7 @@ public <T> TypeAdapter<T> getAdapter(TypeToken<T> type) {
for (TypeAdapterFactory factory : factories) {
TypeAdapter<T> candidate = factory.create(this, type);
if (candidate != null) {
@SuppressWarnings("unchecked")
TypeAdapter<T> existingAdapter = (TypeAdapter<T>) typeTokenCache.putIfAbsent(type, candidate);
// If other thread concurrently added adapter prefer that one instead
if (existingAdapter != null) {
Expand Down Expand Up @@ -780,17 +783,17 @@ public void toJson(Object src, Type typeOfSrc, Appendable writer) throws JsonIOE
*
* @throws JsonIOException if there was a problem writing to the writer
*/
@SuppressWarnings("unchecked")
public void toJson(Object src, Type typeOfSrc, JsonWriter writer) throws JsonIOException {
TypeAdapter<?> adapter = getAdapter(TypeToken.get(typeOfSrc));
@SuppressWarnings("unchecked")
TypeAdapter<Object> adapter = (TypeAdapter<Object>) getAdapter(TypeToken.get(typeOfSrc));
boolean oldLenient = writer.isLenient();
writer.setLenient(true);
boolean oldHtmlSafe = writer.isHtmlSafe();
writer.setHtmlSafe(htmlSafe);
boolean oldSerializeNulls = writer.getSerializeNulls();
writer.setSerializeNulls(serializeNulls);
try {
((TypeAdapter<Object>) adapter).write(writer, src);
adapter.write(writer, src);
} catch (IOException e) {
throw new JsonIOException(e);
} catch (AssertionError e) {
Expand Down Expand Up @@ -957,12 +960,12 @@ public <T> T fromJson(String json, Class<T> classOfT) throws JsonSyntaxException
* @throws JsonParseException if json is not a valid representation for an object of type typeOfT
* @throws JsonSyntaxException if json is not a valid representation for an object of type
*/
@SuppressWarnings("unchecked")
public <T> T fromJson(String json, Type typeOfT) throws JsonSyntaxException {
if (json == null) {
return null;
}
StringReader reader = new StringReader(json);
@SuppressWarnings("unchecked")
T target = (T) fromJson(reader, typeOfT);
return target;
}
Expand Down Expand Up @@ -1017,9 +1020,9 @@ public <T> T fromJson(Reader json, Class<T> classOfT) throws JsonSyntaxException
* @throws JsonSyntaxException if json is not a valid representation for an object of type
* @since 1.2
*/
@SuppressWarnings("unchecked")
public <T> T fromJson(Reader json, Type typeOfT) throws JsonIOException, JsonSyntaxException {
JsonReader jsonReader = newJsonReader(json);
@SuppressWarnings("unchecked")
T object = (T) fromJson(jsonReader, typeOfT);
assertFullConsumption(object, jsonReader);
return object;
Expand Down Expand Up @@ -1052,14 +1055,14 @@ private static void assertFullConsumption(Object obj, JsonReader reader) {
* @throws JsonIOException if there was a problem writing to the Reader
* @throws JsonSyntaxException if json is not a valid representation for an object of type
*/
@SuppressWarnings("unchecked")
public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {
boolean isEmpty = true;
boolean oldLenient = reader.isLenient();
reader.setLenient(true);
try {
reader.peek();
isEmpty = false;
@SuppressWarnings("unchecked")
TypeToken<T> typeToken = (TypeToken<T>) TypeToken.get(typeOfT);
TypeAdapter<T> typeAdapter = getAdapter(typeToken);
T object = typeAdapter.read(reader);
Expand Down
12 changes: 7 additions & 5 deletions gson/src/main/java/com/google/gson/GsonBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -541,22 +541,23 @@ public GsonBuilder setDateFormat(int dateStyle, int timeStyle) {
* {@link InstanceCreator}, {@link JsonSerializer}, and a {@link JsonDeserializer} interfaces.
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public GsonBuilder registerTypeAdapter(Type type, Object typeAdapter) {
Objects.requireNonNull(type);
$Gson$Preconditions.checkArgument(typeAdapter instanceof JsonSerializer<?>
|| typeAdapter instanceof JsonDeserializer<?>
|| typeAdapter instanceof InstanceCreator<?>
|| typeAdapter instanceof TypeAdapter<?>);
if (typeAdapter instanceof InstanceCreator<?>) {
instanceCreators.put(type, (InstanceCreator) typeAdapter);
instanceCreators.put(type, (InstanceCreator<?>) typeAdapter);
}
if (typeAdapter instanceof JsonSerializer<?> || typeAdapter instanceof JsonDeserializer<?>) {
TypeToken<?> typeToken = TypeToken.get(type);
factories.add(TreeTypeAdapter.newFactoryWithMatchRawType(typeToken, typeAdapter));
}
if (typeAdapter instanceof TypeAdapter<?>) {
factories.add(TypeAdapters.newFactory(TypeToken.get(type), (TypeAdapter)typeAdapter));
@SuppressWarnings({"unchecked", "rawtypes"})
TypeAdapterFactory factory = TypeAdapters.newFactory(TypeToken.get(type), (TypeAdapter)typeAdapter);
factories.add(factory);
}
return this;
}
Expand Down Expand Up @@ -589,7 +590,6 @@ public GsonBuilder registerTypeAdapterFactory(TypeAdapterFactory factory) {
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
* @since 1.7
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public GsonBuilder registerTypeHierarchyAdapter(Class<?> baseType, Object typeAdapter) {
Objects.requireNonNull(baseType);
$Gson$Preconditions.checkArgument(typeAdapter instanceof JsonSerializer<?>
Expand All @@ -599,7 +599,9 @@ public GsonBuilder registerTypeHierarchyAdapter(Class<?> baseType, Object typeAd
hierarchyFactories.add(TreeTypeAdapter.newTypeHierarchyFactory(baseType, typeAdapter));
}
if (typeAdapter instanceof TypeAdapter<?>) {
factories.add(TypeAdapters.newTypeHierarchyFactory(baseType, (TypeAdapter)typeAdapter));
@SuppressWarnings({"unchecked", "rawtypes"})
TypeAdapterFactory factory = TypeAdapters.newTypeHierarchyFactory(baseType, (TypeAdapter)typeAdapter);
factories.add(factory);
}
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
*
* @author Inderjeet Singh
*/
@SuppressWarnings("serial") // ignore warning about missing serialVersionUID
public final class LazilyParsedNumber extends Number {
private final String value;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
*
* <p>This implementation was derived from Android 4.1's TreeMap class.
*/
@SuppressWarnings("serial") // ignore warning about missing serialVersionUID
public final class LinkedTreeMap<K, V> extends AbstractMap<K, V> implements Serializable {
@SuppressWarnings({ "unchecked", "rawtypes" }) // to avoid Comparable<Comparable<Comparable<...>>>
private static final Comparator<Comparable> NATURAL_ORDER = new Comparator<Comparable>() {
Expand Down Expand Up @@ -504,10 +505,9 @@ static final class Node<K, V> implements Entry<K, V> {
return oldValue;
}

@SuppressWarnings("rawtypes")
@Override public boolean equals(Object o) {
if (o instanceof Entry) {
Entry other = (Entry) o;
Entry<?, ?> other = (Entry<?, ?>) o;
return (key == null ? other.getKey() == null : key.equals(other.getKey()))
&& (value == null ? other.getValue() == null : value.equals(other.getValue()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
*/
public final class ArrayTypeAdapter<E> extends TypeAdapter<Object> {
public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
@SuppressWarnings({"unchecked", "rawtypes"})
@Override public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
Type type = typeToken.getType();
if (!(type instanceof GenericArrayType || type instanceof Class && ((Class<?>) type).isArray())) {
Expand All @@ -44,8 +43,11 @@ public final class ArrayTypeAdapter<E> extends TypeAdapter<Object> {

Type componentType = $Gson$Types.getArrayComponentType(type);
TypeAdapter<?> componentTypeAdapter = gson.getAdapter(TypeToken.get(componentType));
return new ArrayTypeAdapter(

@SuppressWarnings({"unchecked", "rawtypes"})
TypeAdapter<T> arrayAdapter = new ArrayTypeAdapter(
gson, componentTypeAdapter, $Gson$Types.getRawType(componentType));
return arrayAdapter;
}
};

Expand Down Expand Up @@ -89,7 +91,6 @@ public ArrayTypeAdapter(Gson context, TypeAdapter<E> componentTypeAdapter, Class
}
}

@SuppressWarnings("unchecked")
@Override public void write(JsonWriter out, Object array) throws IOException {
if (array == null) {
out.nullValue();
Expand All @@ -98,6 +99,7 @@ public ArrayTypeAdapter(Gson context, TypeAdapter<E> componentTypeAdapter, Class

out.beginArray();
for (int i = 0, length = Array.getLength(array); i < length; i++) {
@SuppressWarnings("unchecked")
E value = (E) Array.get(array, i);
componentTypeAdapter.write(out, value);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public JsonAdapterAnnotationTypeAdapterFactory(ConstructorConstructor constructo
this.constructorConstructor = constructorConstructor;
}

@SuppressWarnings("unchecked")
@SuppressWarnings("unchecked") // this is not safe; requires that user has specified correct adapter class for @JsonAdapter
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> targetType) {
Class<? super T> rawType = targetType.getRawType();
Expand All @@ -49,7 +49,6 @@ public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> targetType) {
return (TypeAdapter<T>) getTypeAdapter(constructorConstructor, gson, targetType, annotation);
}

@SuppressWarnings({ "unchecked", "rawtypes" }) // Casts guarded by conditionals.
TypeAdapter<?> getTypeAdapter(ConstructorConstructor constructorConstructor, Gson gson,
TypeToken<?> type, JsonAdapter annotation) {
Object instance = constructorConstructor.get(TypeToken.get(annotation.value())).construct();
Expand All @@ -62,12 +61,16 @@ TypeAdapter<?> getTypeAdapter(ConstructorConstructor constructorConstructor, Gso
typeAdapter = ((TypeAdapterFactory) instance).create(gson, type);
} else if (instance instanceof JsonSerializer || instance instanceof JsonDeserializer) {
JsonSerializer<?> serializer = instance instanceof JsonSerializer
? (JsonSerializer) instance
? (JsonSerializer<?>) instance
: null;
JsonDeserializer<?> deserializer = instance instanceof JsonDeserializer
? (JsonDeserializer) instance
? (JsonDeserializer<?>) instance
: null;
typeAdapter = new TreeTypeAdapter(serializer, deserializer, gson, type, null, nullSafe);

@SuppressWarnings({ "unchecked", "rawtypes" })
TypeAdapter<?> tempAdapter = new TreeTypeAdapter(serializer, deserializer, gson, type, null, nullSafe);
typeAdapter = tempAdapter;

nullSafe = false;
} else {
throw new IllegalArgumentException("Invalid attempt to bind an instance of "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,13 +166,13 @@ private Object readTerminal(JsonReader in, JsonToken peeked) throws IOException
}
}

@SuppressWarnings("unchecked")
@Override public void write(JsonWriter out, Object value) throws IOException {
if (value == null) {
out.nullValue();
return;
}

@SuppressWarnings("unchecked")
TypeAdapter<Object> typeAdapter = (TypeAdapter<Object>) gson.getAdapter(value.getClass());
if (typeAdapter instanceof ObjectTypeAdapter) {
out.beginObject();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,19 +126,19 @@ private ReflectiveTypeAdapterFactory.BoundField createBoundField(
final TypeToken<?> fieldType, boolean serialize, boolean deserialize,
final boolean blockInaccessible) {
final boolean isPrimitive = Primitives.isPrimitive(fieldType.getRawType());
// special casing primitives here saves ~5% on Android...
JsonAdapter annotation = field.getAnnotation(JsonAdapter.class);
TypeAdapter<?> mapped = null;
if (annotation != null) {
// This is not safe; requires that user has specified correct adapter class for @JsonAdapter
mapped = jsonAdapterFactory.getTypeAdapter(
constructorConstructor, context, fieldType, annotation);
}
final boolean jsonAdapterPresent = mapped != null;
if (mapped == null) mapped = context.getAdapter(fieldType);

final TypeAdapter<?> typeAdapter = mapped;
@SuppressWarnings("unchecked")
final TypeAdapter<Object> typeAdapter = (TypeAdapter<Object>) mapped;
return new ReflectiveTypeAdapterFactory.BoundField(name, serialize, deserialize) {
@SuppressWarnings({"unchecked", "rawtypes"}) // the type adapter and field type always agree
@Override void write(JsonWriter writer, Object value)
throws IOException, IllegalAccessException {
if (!serialized) return;
Expand All @@ -152,8 +152,8 @@ private ReflectiveTypeAdapterFactory.BoundField createBoundField(
return;
}
writer.name(name);
TypeAdapter t = jsonAdapterPresent ? typeAdapter
: new TypeAdapterRuntimeTypeWrapper(context, typeAdapter, fieldType.getType());
TypeAdapter<Object> t = jsonAdapterPresent ? typeAdapter
: new TypeAdapterRuntimeTypeWrapper<>(context, typeAdapter, fieldType.getType());
t.write(writer, fieldValue);
}
@Override void read(JsonReader reader, Object value)
Expand Down
Loading

0 comments on commit 3583373

Please sign in to comment.