Skip to content

Commit

Permalink
Merge branch 'master' into optional-sql
Browse files Browse the repository at this point in the history
  • Loading branch information
eamonnmcmanus committed Aug 24, 2021
2 parents a4a235e + 03be835 commit 69173b0
Show file tree
Hide file tree
Showing 21 changed files with 459 additions and 84 deletions.
6 changes: 6 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
version: 2
updates:
- package-ecosystem: "maven"
directory: "/"
schedule:
interval: "daily"
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
Change Log
==========

## Version 2.8.8

* Fixed issue with recursive types (#1390).
* Better behaviour with Java 9+ and `Unsafe` if there is a security manager (#1712).
* `EnumTypeAdapter` now works better when ProGuard has obfuscated enum fields (#1495).

## Version 2.8.7

* Fixed `ISO8601UtilsTest` failing on systems with UTC+X.
* Improved javadoc for `JsonStreamParser`.
* Updated proguard.cfg (#1693).
* Fixed `IllegalStateException` in `JsonTreeWriter` (#1592).
* Added `JsonArray.isEmpty()` (#1640).
* Added new test cases (#1638).
* Fixed OSGi metadata generation to work on JavaSE < 9 (#1603).

## Version 2.8.6
_2019-10-04_ [GitHub Diff](https://github.com/google/gson/compare/gson-parent-2.8.5...gson-parent-2.8.6)
* Added static methods `JsonParser.parseString` and `JsonParser.parseReader` and deprecated instance method `JsonParser.parse`
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ There are a few open-source projects that can convert Java objects to JSON. Howe
Gradle:
```gradle
dependencies {
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'com.google.code.gson:gson:2.8.8'
}
```

Expand All @@ -26,7 +26,7 @@ Maven:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
<version>2.8.8</version>
</dependency>
```

Expand Down
4 changes: 2 additions & 2 deletions UserGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ The Gson instance does not maintain any state while invoking Json operations. So
## <a name="TOC-Gson-With-Gradle"></a>Using Gson with Gradle/Android
```
dependencies {
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'com.google.code.gson:gson:2.8.8'
}
```
## <a name="TOC-Gson-With-Maven"></a>Using Gson with Maven
Expand All @@ -86,7 +86,7 @@ To use Gson with Maven2/3, you can use the Gson version available in Maven Centr
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
<version>2.8.8</version>
<scope>compile</scope>
</dependency>
</dependencies>
Expand Down
2 changes: 1 addition & 1 deletion codegen/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.2</version>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
</dependencies>
Expand Down
6 changes: 5 additions & 1 deletion examples/android-proguard-example/proguard.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

# Prevent proguard from stripping interface information from TypeAdapter, TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
-keep class * implements com.google.gson.TypeAdapter
-keep class * extends com.google.gson.TypeAdapter
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
Expand All @@ -25,4 +25,8 @@
@com.google.gson.annotations.SerializedName <fields>;
}

# Retain generic signatures of TypeToken and its subclasses with R8 version 3.0 and higher.
-keep,allowobfuscation,allowshrinking class com.google.gson.reflect.TypeToken
-keep,allowobfuscation,allowshrinking class * extends com.google.gson.reflect.TypeToken

##---------------End: proguard configuration for Gson ----------
2 changes: 1 addition & 1 deletion extras/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.2</version>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
</dependencies>
Expand Down
91 changes: 89 additions & 2 deletions gson/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>com.google.code.gson</groupId>
<artifactId>gson-parent</artifactId>
<version>2.8.7-SNAPSHOT</version>
<version>2.8.9-SNAPSHOT</version>
</parent>

<artifactId>gson</artifactId>
Expand All @@ -16,6 +16,12 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<version>2.4.0</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand All @@ -34,7 +40,7 @@
<plugin>
<groupId>biz.aQute.bnd</groupId>
<artifactId>bnd-maven-plugin</artifactId>
<version>4.0.0</version>
<version>5.3.0</version>
<executions>
<execution>
<goals>
Expand Down Expand Up @@ -69,6 +75,87 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.coderplus.maven.plugins</groupId>
<artifactId>copy-rename-maven-plugin</artifactId>
<version>1.0.1</version>
<executions>
<execution>
<id>pre-obfuscate-class</id>
<phase>process-test-classes</phase>
<goals>
<goal>rename</goal>
</goals>
<configuration>
<fileSets>
<fileSet>
<sourceFile>${project.build.directory}/test-classes/com/google/gson/functional/EnumWithObfuscatedTest.class</sourceFile>
<destinationFile>${project.build.directory}/test-classes-obfuscated-injar/com/google/gson/functional/EnumWithObfuscatedTest.class</destinationFile>
</fileSet>
<fileSet>
<sourceFile>${project.build.directory}/test-classes/com/google/gson/functional/EnumWithObfuscatedTest$Gender.class</sourceFile>
<destinationFile>${project.build.directory}/test-classes-obfuscated-injar/com/google/gson/functional/EnumWithObfuscatedTest$Gender.class</destinationFile>
</fileSet>
</fileSets>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<executions>
<execution>
<phase>process-test-classes</phase>
<goals><goal>proguard</goal></goals>
</execution>
</executions>
<configuration>
<proguardVersion>6.2.2</proguardVersion>
<obfuscate>true</obfuscate>
<injar>test-classes-obfuscated-injar</injar>
<outjar>test-classes-obfuscated-outjar</outjar>
<inFilter>**/*.class</inFilter>
<proguardInclude>${basedir}/src/test/resources/testcases-proguard.conf</proguardInclude>
<libs>
<lib>${project.build.directory}/classes</lib>
<lib>${java.home}/jmods/java.base.jmod</lib>
</libs>
</configuration>
<dependencies>
<dependency>
<groupId>net.sf.proguard</groupId>
<artifactId>proguard-base</artifactId>
<version>6.2.2</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>post-obfuscate-class</id>
<phase>process-test-classes</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/test-classes/com/google/gson/functional</outputDirectory>
<resources>
<resource>
<directory>${project.build.directory}/test-classes-obfuscated-outjar/com/google/gson/functional</directory>
<includes>
<include>EnumWithObfuscatedTest.class</include>
<include>EnumWithObfuscatedTest$Gender.class</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
16 changes: 10 additions & 6 deletions gson/src/main/java/com/google/gson/JsonStreamParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@

/**
* A streaming parser that allows reading of multiple {@link JsonElement}s from the specified reader
* asynchronously.
*
* asynchronously. The JSON data is parsed in lenient mode, see also
* {@link JsonReader#setLenient(boolean)}.
*
* <p>This class is conditionally thread-safe (see Item 70, Effective Java second edition). To
* properly use this class across multiple threads, you will need to add some external
* synchronization. For example:
Expand Down Expand Up @@ -72,10 +73,12 @@ public JsonStreamParser(Reader reader) {
}

/**
* Returns the next available {@link JsonElement} on the reader. Null if none available.
*
* @return the next available {@link JsonElement} on the reader. Null if none available.
* @throws JsonParseException if the incoming stream is malformed JSON.
* Returns the next available {@link JsonElement} on the reader. Throws a
* {@link NoSuchElementException} if no element is available.
*
* @return the next available {@code JsonElement} on the reader.
* @throws JsonSyntaxException if the incoming stream is malformed JSON.
* @throws NoSuchElementException if no {@code JsonElement} is available.
* @since 1.4
*/
public JsonElement next() throws JsonParseException {
Expand All @@ -97,6 +100,7 @@ public JsonElement next() throws JsonParseException {
/**
* Returns true if a {@link JsonElement} is available on the input for consumption
* @return true if a {@link JsonElement} is available on the input, false otherwise
* @throws JsonSyntaxException if the incoming stream is malformed JSON.
* @since 1.4
*/
public boolean hasNext() {
Expand Down
58 changes: 41 additions & 17 deletions gson/src/main/java/com/google/gson/internal/$Gson$Types.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.util.*;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Properties;

import static com.google.gson.internal.$Gson$Preconditions.checkArgument;
import static com.google.gson.internal.$Gson$Preconditions.checkNotNull;
Expand Down Expand Up @@ -334,52 +339,62 @@ public static Type[] getMapKeyAndValueTypes(Type context, Class<?> contextRawTyp
}

public static Type resolve(Type context, Class<?> contextRawType, Type toResolve) {
return resolve(context, contextRawType, toResolve, new HashSet<TypeVariable<?>>());

return resolve(context, contextRawType, toResolve, new HashMap<TypeVariable<?>, Type>());
}

private static Type resolve(Type context, Class<?> contextRawType, Type toResolve,
Collection<TypeVariable<?>> visitedTypeVariables) {
Map<TypeVariable<?>, Type> visitedTypeVariables) {
// this implementation is made a little more complicated in an attempt to avoid object-creation
TypeVariable<?> resolving = null;
while (true) {
if (toResolve instanceof TypeVariable) {
TypeVariable<?> typeVariable = (TypeVariable<?>) toResolve;
if (visitedTypeVariables.contains(typeVariable)) {
Type previouslyResolved = visitedTypeVariables.get(typeVariable);
if (previouslyResolved != null) {
// cannot reduce due to infinite recursion
return toResolve;
} else {
visitedTypeVariables.add(typeVariable);
return (previouslyResolved == Void.TYPE) ? toResolve : previouslyResolved;
}

// Insert a placeholder to mark the fact that we are in the process of resolving this type
visitedTypeVariables.put(typeVariable, Void.TYPE);
if (resolving == null) {
resolving = typeVariable;
}

toResolve = resolveTypeVariable(context, contextRawType, typeVariable);
if (toResolve == typeVariable) {
return toResolve;
break;
}

} else if (toResolve instanceof Class && ((Class<?>) toResolve).isArray()) {
Class<?> original = (Class<?>) toResolve;
Type componentType = original.getComponentType();
Type newComponentType = resolve(context, contextRawType, componentType, visitedTypeVariables);
return componentType == newComponentType
toResolve = equal(componentType, newComponentType)
? original
: arrayOf(newComponentType);
break;

} else if (toResolve instanceof GenericArrayType) {
GenericArrayType original = (GenericArrayType) toResolve;
Type componentType = original.getGenericComponentType();
Type newComponentType = resolve(context, contextRawType, componentType, visitedTypeVariables);
return componentType == newComponentType
toResolve = equal(componentType, newComponentType)
? original
: arrayOf(newComponentType);
break;

} else if (toResolve instanceof ParameterizedType) {
ParameterizedType original = (ParameterizedType) toResolve;
Type ownerType = original.getOwnerType();
Type newOwnerType = resolve(context, contextRawType, ownerType, visitedTypeVariables);
boolean changed = newOwnerType != ownerType;
boolean changed = !equal(newOwnerType, ownerType);

Type[] args = original.getActualTypeArguments();
for (int t = 0, length = args.length; t < length; t++) {
Type resolvedTypeArgument = resolve(context, contextRawType, args[t], visitedTypeVariables);
if (resolvedTypeArgument != args[t]) {
if (!equal(resolvedTypeArgument, args[t])) {
if (!changed) {
args = args.clone();
changed = true;
Expand All @@ -388,9 +403,10 @@ private static Type resolve(Type context, Class<?> contextRawType, Type toResolv
}
}

return changed
toResolve = changed
? newParameterizedTypeWithOwner(newOwnerType, original.getRawType(), args)
: original;
break;

} else if (toResolve instanceof WildcardType) {
WildcardType original = (WildcardType) toResolve;
Expand All @@ -400,20 +416,28 @@ private static Type resolve(Type context, Class<?> contextRawType, Type toResolv
if (originalLowerBound.length == 1) {
Type lowerBound = resolve(context, contextRawType, originalLowerBound[0], visitedTypeVariables);
if (lowerBound != originalLowerBound[0]) {
return supertypeOf(lowerBound);
toResolve = supertypeOf(lowerBound);
break;
}
} else if (originalUpperBound.length == 1) {
Type upperBound = resolve(context, contextRawType, originalUpperBound[0], visitedTypeVariables);
if (upperBound != originalUpperBound[0]) {
return subtypeOf(upperBound);
toResolve = subtypeOf(upperBound);
break;
}
}
return original;
toResolve = original;
break;

} else {
return toResolve;
break;
}
}
// ensure that any in-process resolution gets updated with the final result
if (resolving != null) {
visitedTypeVariables.put(resolving, toResolve);
}
return toResolve;
}

static Type resolveTypeVariable(Type context, Class<?> contextRawType, TypeVariable<?> unknown) {
Expand Down

0 comments on commit 69173b0

Please sign in to comment.