mirror of
https://github.com/github/codeql.git
synced 2026-04-28 18:25:24 +02:00
Add Gson support to unsafe deserialization query
This commit is contained in:
@@ -77,6 +77,8 @@ private import FlowSummary
|
||||
*/
|
||||
private module Frameworks {
|
||||
private import internal.ContainerFlow
|
||||
private import semmle.code.java.frameworks.android.Android
|
||||
private import semmle.code.java.frameworks.android.Intent
|
||||
private import semmle.code.java.frameworks.android.XssSinks
|
||||
private import semmle.code.java.frameworks.android.Intent
|
||||
private import semmle.code.java.frameworks.ApacheHttp
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.ExternalFlow
|
||||
import semmle.code.xml.AndroidManifest
|
||||
private import semmle.code.java.dataflow.ExternalFlow
|
||||
|
||||
/**
|
||||
* Gets a transitive superType avoiding magic optimisation
|
||||
@@ -202,3 +203,59 @@ private class ContentProviderSourceModels extends SourceModelCsv {
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
/** Interface for classes whose instances can be written to and restored from a Parcel. */
|
||||
class TypeParcelable extends Interface {
|
||||
TypeParcelable() { this.hasQualifiedName("android.os", "Parcelable") }
|
||||
}
|
||||
|
||||
/**
|
||||
* A method that overrides `android.os.Parcelable.Creator.createFromParcel`.
|
||||
*/
|
||||
class CreateFromParcelMethod extends Method {
|
||||
CreateFromParcelMethod() {
|
||||
this.hasName("createFromParcel") and
|
||||
this.getEnclosingCallable().getDeclaringType().getASupertype*() instanceof TypeParcelable
|
||||
}
|
||||
}
|
||||
|
||||
private class TaintPropagationModels extends SummaryModelCsv {
|
||||
override predicate row(string s) {
|
||||
// BaseBundle getters
|
||||
s =
|
||||
"android.os;BaseBundle;true;get" + ["Boolean", "Double", "Int", "Long", "String"] +
|
||||
["", "Array"] + ";;;Argument[-1];ReturnValue;taint"
|
||||
or
|
||||
// Bundle getters
|
||||
s =
|
||||
"android.os;Bundle;true;get" +
|
||||
[
|
||||
"Binder", "Bundle", "Byte", "ByteArray", "Char", "CharArray", "CharSequence",
|
||||
"CharSequenceArray", "CharSequenceArrayList", "Float", "FloatArray", "IntegerArrayList",
|
||||
"Parcelable", "ParcelableArray", "ParcelableArrayList", "Serializable", "Short",
|
||||
"ShortArray", "Size", "SizeF", "SparseParcelableArray", "StringArrayList"
|
||||
] + ";;;Argument[-1];ReturnValue;taint"
|
||||
or
|
||||
// Intent readers that return their value
|
||||
s =
|
||||
"android.os;Parcel;false;read" +
|
||||
[
|
||||
"Array", "ArrayList", "Boolean", "Bundle", "Byte", "Double", "FileDescriptor", "Float",
|
||||
"HashMap", "Int", "Long", "Parcelable", "ParcelableArray", "PersistableBundle",
|
||||
"Serializable", "Size", "SizeF", "SparseArray", "SparseBolleanArray", "String",
|
||||
"StrongBinder", "TypedObject", "Value"
|
||||
] + ";;;Argument[-1];ReturnValue;taint"
|
||||
or
|
||||
// Intent readers that write to an existing object
|
||||
s =
|
||||
"android.os;Parcel;false;read" +
|
||||
[
|
||||
"BinderArray", "BinderList", "BooleanArray", "ByteArray", "CharArray", "DoubleArray",
|
||||
"FloatArray", "IntArray", "List", "LongArray", "Map", "ParcelableList", "StringArray",
|
||||
"StringList", "TypedArray", "TypedList"
|
||||
] + ";;;Argument[-1];Argument[0];taint"
|
||||
or
|
||||
// One Intent method that aliases an argument to a return value
|
||||
s = "android.os;Parcel;false;readParcelableList;;;Argument[0];ReturnValue;value"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,32 +3,53 @@ private import semmle.code.java.dataflow.DataFlow
|
||||
import semmle.code.java.dataflow.FlowSteps
|
||||
import semmle.code.java.dataflow.ExternalFlow
|
||||
|
||||
/**
|
||||
* The class `android.content.Intent`.
|
||||
*/
|
||||
class TypeIntent extends Class {
|
||||
TypeIntent() { hasQualifiedName("android.content", "Intent") }
|
||||
}
|
||||
|
||||
/**
|
||||
* The class `android.app.Activity`.
|
||||
*/
|
||||
class TypeActivity extends Class {
|
||||
TypeActivity() { hasQualifiedName("android.app", "Activity") }
|
||||
}
|
||||
|
||||
/**
|
||||
* The class `android.content.Context`.
|
||||
*/
|
||||
class TypeContext extends RefType {
|
||||
TypeContext() { hasQualifiedName("android.content", "Context") }
|
||||
}
|
||||
|
||||
/**
|
||||
* The class `android.content.BroadcastReceiver`.
|
||||
*/
|
||||
class TypeBroadcastReceiver extends Class {
|
||||
TypeBroadcastReceiver() { hasQualifiedName("android.content", "BroadcastReceiver") }
|
||||
}
|
||||
|
||||
/**
|
||||
* The method `Activity.getIntent`
|
||||
*/
|
||||
class AndroidGetIntentMethod extends Method {
|
||||
AndroidGetIntentMethod() { hasName("getIntent") and getDeclaringType() instanceof TypeActivity }
|
||||
}
|
||||
|
||||
/**
|
||||
* The method `BroadcastReceiver.onReceive`.
|
||||
*/
|
||||
class AndroidReceiveIntentMethod extends Method {
|
||||
AndroidReceiveIntentMethod() {
|
||||
hasName("onReceive") and getDeclaringType() instanceof TypeBroadcastReceiver
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The method `Context.startActivity` or `startActivities`.
|
||||
*/
|
||||
class ContextStartActivityMethod extends Method {
|
||||
ContextStartActivityMethod() {
|
||||
(hasName("startActivity") or hasName("startActivities")) and
|
||||
@@ -44,6 +65,16 @@ private class IntentFieldsInheritTaint extends DataFlow::SyntheticFieldContent,
|
||||
IntentFieldsInheritTaint() { this.getField().matches("android.content.Intent.%") }
|
||||
}
|
||||
|
||||
/**
|
||||
* The method `Intent.getParcelableExtra`.
|
||||
*/
|
||||
class IntentGetParcelableExtraMethod extends Method {
|
||||
IntentGetParcelableExtraMethod() {
|
||||
hasName("getParcelableExtra") and
|
||||
getDeclaringType() instanceof TypeIntent
|
||||
}
|
||||
}
|
||||
|
||||
private class IntentBundleFlowSteps extends SummaryModelCsv {
|
||||
override predicate row(string row) {
|
||||
row =
|
||||
|
||||
35
java/ql/lib/semmle/code/java/frameworks/google/Gson.qll
Normal file
35
java/ql/lib/semmle/code/java/frameworks/google/Gson.qll
Normal file
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Provides classes for working with the Gson framework.
|
||||
*/
|
||||
|
||||
import java
|
||||
import semmle.code.java.dataflow.DataFlow
|
||||
import semmle.code.java.frameworks.android.Android
|
||||
import semmle.code.java.frameworks.android.Intent
|
||||
|
||||
/** The class `com.google.gson.Gson`. */
|
||||
class Gson extends RefType {
|
||||
Gson() { this.hasQualifiedName("com.google.gson", "Gson") }
|
||||
}
|
||||
|
||||
/** The `fromJson` deserialization method. */
|
||||
class GsonDeserializeMethod extends Method {
|
||||
GsonDeserializeMethod() {
|
||||
this.getDeclaringType() instanceof Gson and
|
||||
this.hasName("fromJson")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `intentNode` is an `Intent` used in the context `(T)intentNode.getParcelableExtra(...)` and
|
||||
* `parcelNode` is the corresponding parameter of `Parcelable.Creator<T> { public T createFromParcel(Parcel parcelNode) { }`.
|
||||
*/
|
||||
predicate intentFlowsToParcel(DataFlow::Node intentNode, DataFlow::Node parcelNode) {
|
||||
exists(MethodAccess getParcelableExtraCall, CreateFromParcelMethod cfpm, Type createdType |
|
||||
intentNode.asExpr() = getParcelableExtraCall.getQualifier() and
|
||||
getParcelableExtraCall.getMethod() instanceof IntentGetParcelableExtraMethod and
|
||||
DataFlow::localExprFlow(getParcelableExtraCall, any(Expr e | e.getType() = createdType)) and
|
||||
parcelNode.asParameter() = cfpm.getParameter(0) and
|
||||
cfpm.getReturnType() = createdType
|
||||
)
|
||||
}
|
||||
@@ -17,6 +17,7 @@ private import semmle.code.java.frameworks.Jackson
|
||||
private import semmle.code.java.frameworks.Jabsorb
|
||||
private import semmle.code.java.frameworks.JoddJson
|
||||
private import semmle.code.java.frameworks.Flexjson
|
||||
private import semmle.code.java.frameworks.google.Gson
|
||||
private import semmle.code.java.frameworks.apache.Lang
|
||||
private import semmle.code.java.Reflection
|
||||
|
||||
@@ -207,6 +208,10 @@ predicate unsafeDeserialization(MethodAccess ma, Expr sink) {
|
||||
or
|
||||
m instanceof FlexjsonDeserializeMethod and
|
||||
sink = ma.getArgument(0)
|
||||
or
|
||||
m instanceof GsonDeserializeMethod and
|
||||
sink = ma.getArgument(0) and
|
||||
any(UnsafeTypeConfig config).hasFlowToExpr(ma.getArgument(1))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -249,6 +254,8 @@ class UnsafeDeserializationConfig extends TaintTracking::Configuration {
|
||||
createJacksonJsonParserStep(pred, succ)
|
||||
or
|
||||
createJacksonTreeNodeStep(pred, succ)
|
||||
or
|
||||
intentFlowsToParcel(pred, succ)
|
||||
}
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
@@ -362,9 +369,15 @@ class UnsafeTypeConfig extends TaintTracking2::Configuration {
|
||||
ma.getMethod() instanceof JabsorbUnmarshallMethod
|
||||
or
|
||||
ma.getMethod() instanceof JoddJsonParseMethod
|
||||
or
|
||||
ma.getMethod() instanceof GsonDeserializeMethod
|
||||
) and
|
||||
// Note `JacksonTypeDescriptorType` includes plain old `java.lang.Class`
|
||||
arg.getType() instanceof JacksonTypeDescriptorType and
|
||||
(
|
||||
arg.getType() instanceof JacksonTypeDescriptorType
|
||||
or
|
||||
arg.getType().(RefType).hasQualifiedName("java.lang.reflect", "Type")
|
||||
) and
|
||||
arg = sink.asExpr()
|
||||
)
|
||||
}
|
||||
@@ -375,7 +388,8 @@ class UnsafeTypeConfig extends TaintTracking2::Configuration {
|
||||
*/
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node fromNode, DataFlow::Node toNode) {
|
||||
resolveClassStep(fromNode, toNode) or
|
||||
looksLikeResolveClassStep(fromNode, toNode)
|
||||
looksLikeResolveClassStep(fromNode, toNode) or
|
||||
intentFlowsToParcel(fromNode, toNode)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
24
java/ql/test/query-tests/security/CWE-502/AndroidManifest.xml
Executable file
24
java/ql/test/query-tests/security/CWE-502/AndroidManifest.xml
Executable file
@@ -0,0 +1,24 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.example.app"
|
||||
android:installLocation="auto"
|
||||
android:versionCode="1"
|
||||
android:versionName="0.1" >
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<application
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme" >
|
||||
<activity
|
||||
android:name=".GsonActivity"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
17
java/ql/test/query-tests/security/CWE-502/GsonActivity.java
Normal file
17
java/ql/test/query-tests/security/CWE-502/GsonActivity.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package com.example.app;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class GsonActivity extends Activity {
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(-1);
|
||||
|
||||
ParcelableEntity entity = (ParcelableEntity) getIntent().getParcelableExtra("jsonEntity");
|
||||
}
|
||||
}
|
||||
77
java/ql/test/query-tests/security/CWE-502/GsonServlet.java
Normal file
77
java/ql/test/query-tests/security/CWE-502/GsonServlet.java
Normal file
@@ -0,0 +1,77 @@
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.typeadapters.RuntimeTypeAdapterFactory;
|
||||
|
||||
import com.example.User;
|
||||
import com.thirdparty.Person;
|
||||
|
||||
public class GsonServlet extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
// GOOD: concrete class type specified
|
||||
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
|
||||
String json = req.getParameter("json");
|
||||
|
||||
Gson gson = new Gson();
|
||||
Object obj = gson.fromJson(json, User.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
// GOOD: concrete class type specified
|
||||
public void doPut(HttpServletRequest req, HttpServletResponse resp) throws IOException {
|
||||
String json = req.getParameter("json");
|
||||
|
||||
Gson gson = new Gson();
|
||||
Object obj = gson.fromJson(json, Person.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
// BAD: allow class name to be controlled by remote source
|
||||
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
|
||||
String json = req.getParameter("json");
|
||||
String clazz = req.getParameter("class");
|
||||
|
||||
try {
|
||||
Gson gson = new Gson();
|
||||
Object obj = gson.fromJson(json, Class.forName(clazz)); // $unsafeDeserialization
|
||||
} catch (ClassNotFoundException cne) {
|
||||
throw new IOException(cne.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
// BAD: allow class name to be controlled by remote source even with a type adapter factory
|
||||
public void doHead(HttpServletRequest req, HttpServletResponse resp) throws IOException {
|
||||
String json = req.getParameter("json");
|
||||
String clazz = req.getParameter("class");
|
||||
|
||||
try {
|
||||
RuntimeTypeAdapterFactory<User> runtimeTypeAdapterFactory = RuntimeTypeAdapterFactory
|
||||
.of(User.class, "type");
|
||||
Gson gson = new GsonBuilder().registerTypeAdapterFactory(runtimeTypeAdapterFactory).create();
|
||||
Object obj = gson.fromJson(json, Class.forName(clazz)); // $unsafeDeserialization
|
||||
} catch (ClassNotFoundException cne) {
|
||||
throw new IOException(cne.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
// GOOD: specify allowed class types without explicitly configured vulnerable subclass types
|
||||
public void doTrace(HttpServletRequest req, HttpServletResponse resp) throws IOException {
|
||||
String json = req.getParameter("json");
|
||||
String clazz = req.getParameter("class");
|
||||
|
||||
RuntimeTypeAdapterFactory<Person> runtimeTypeAdapterFactory = RuntimeTypeAdapterFactory
|
||||
.of(Person.class, "type");
|
||||
Gson gson = new GsonBuilder().registerTypeAdapterFactory(runtimeTypeAdapterFactory).create();
|
||||
Person obj = gson.fromJson(json, Person.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.example.app;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
public class ParcelableEntity implements Parcelable {
|
||||
private static final Gson GSON = new GsonBuilder().create();
|
||||
|
||||
public ParcelableEntity(Object obj) {
|
||||
this.obj = obj;
|
||||
}
|
||||
|
||||
private Object obj;
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel parcel, int i) {
|
||||
parcel.writeString(obj.getClass().getName());
|
||||
parcel.writeString(GSON.toJson(obj));
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator CREATOR = new Creator<ParcelableEntity>() {
|
||||
@Override
|
||||
public ParcelableEntity createFromParcel(Parcel parcel) {
|
||||
try {
|
||||
Class clazz = Class.forName(parcel.readString());
|
||||
Object obj = GSON.fromJson(parcel.readString(), clazz); // $unsafeDeserialization
|
||||
return new ParcelableEntity(obj);
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelableEntity[] newArray(int size) {
|
||||
return new ParcelableEntity[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/snakeyaml-1.21:${testdir}/../../../stubs/xstream-1.4.10:${testdir}/../../../stubs/kryo-4.0.2:${testdir}/../../../stubs/jsr311-api-1.1.1:${testdir}/../../../stubs/fastjson-1.2.74:${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/jyaml-1.3:${testdir}/../../../stubs/json-io-4.10.0:${testdir}/../../../stubs/yamlbeans-1.09:${testdir}/../../../stubs/hessian-4.0.38:${testdir}/../../../stubs/castor-1.4.1:${testdir}/../../../stubs/jackson-databind-2.12:${testdir}/../../../stubs/jackson-core-2.12:${testdir}/../../../stubs/jabsorb-1.3.2:${testdir}/../../../stubs/json-java-20210307:${testdir}/../../../stubs/joddjson-6.0.3:${testdir}/../../../stubs/flexjson-2.1
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/snakeyaml-1.21:${testdir}/../../../stubs/xstream-1.4.10:${testdir}/../../../stubs/kryo-4.0.2:${testdir}/../../../stubs/jsr311-api-1.1.1:${testdir}/../../../stubs/fastjson-1.2.74:${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/jyaml-1.3:${testdir}/../../../stubs/json-io-4.10.0:${testdir}/../../../stubs/yamlbeans-1.09:${testdir}/../../../stubs/hessian-4.0.38:${testdir}/../../../stubs/castor-1.4.1:${testdir}/../../../stubs/jackson-databind-2.12:${testdir}/../../../stubs/jackson-core-2.12:${testdir}/../../../stubs/jabsorb-1.3.2:${testdir}/../../../stubs/json-java-20210307:${testdir}/../../../stubs/joddjson-6.0.3:${testdir}/../../../stubs/flexjson-2.1:${testdir}/../../../stubs/gson-2.8.6:${testdir}/../../../stubs/google-android-9.0.0
|
||||
|
||||
@@ -348,6 +348,18 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value associated with the given key, or null if
|
||||
* no mapping of the desired type exists for the given key or a null
|
||||
* value is explicitly associated with the key.
|
||||
*
|
||||
* @param key a String, or null
|
||||
* @return a Parcelable value, or null
|
||||
*/
|
||||
public <T extends Parcelable> T getParcelable(String key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value associated with the given key, or null if no mapping of the
|
||||
* desired type exists for the given key or a null value is explicitly
|
||||
|
||||
@@ -66,6 +66,31 @@ public interface Parcelable {
|
||||
*/
|
||||
public void writeToParcel(Parcel dest, int flags);
|
||||
|
||||
/**
|
||||
* Interface that must be implemented and provided as a public CREATOR
|
||||
* field that generates instances of your Parcelable class from a Parcel.
|
||||
*/
|
||||
public interface Creator<T> {
|
||||
/**
|
||||
* Create a new instance of the Parcelable class, instantiating it
|
||||
* from the given Parcel whose data had previously been written by
|
||||
* {@link Parcelable#writeToParcel Parcelable.writeToParcel()}.
|
||||
*
|
||||
* @param source The Parcel to read the object's data from.
|
||||
* @return Returns a new instance of the Parcelable class.
|
||||
*/
|
||||
public T createFromParcel(Parcel source);
|
||||
|
||||
/**
|
||||
* Create a new array of the Parcelable class.
|
||||
*
|
||||
* @param size Size of the array.
|
||||
* @return Returns an array of the Parcelable class, with every entry
|
||||
* initialized to null.
|
||||
*/
|
||||
public T[] newArray(int size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specialization of {@link Creator} that allows you to receive the ClassLoader
|
||||
* the object is being created in.
|
||||
|
||||
@@ -1,7 +1,38 @@
|
||||
package com.google.gson;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.io.Reader;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
|
||||
public final class Gson {
|
||||
public Gson() {
|
||||
}
|
||||
|
||||
public String toJson(Object src) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String toJson(Object src, Type typeOfSrc) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public <T> T fromJson(String json, Class<T> classOfT) throws JsonSyntaxException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public <T> T fromJson(String json, Type typeOfT) throws JsonSyntaxException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public <T> T fromJson(Reader json, Class<T> classOfT) throws JsonSyntaxException, JsonIOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public <T> T fromJson(Reader json, Type typeOfT) throws JsonIOException, JsonSyntaxException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
99
java/ql/test/stubs/gson-2.8.6/com/google/gson/GsonBuilder.java
generated
Normal file
99
java/ql/test/stubs/gson-2.8.6/com/google/gson/GsonBuilder.java
generated
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.gson;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public final class GsonBuilder {
|
||||
/**
|
||||
* Creates a GsonBuilder instance that can be used to build Gson with various configuration
|
||||
* settings. GsonBuilder follows the builder pattern, and it is typically used by first
|
||||
* invoking various configuration methods to set desired options, and finally calling
|
||||
* {@link #create()}.
|
||||
*/
|
||||
public GsonBuilder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a GsonBuilder instance from a Gson instance. The newly constructed GsonBuilder
|
||||
* has the same configuration as the previously built Gson instance.
|
||||
*
|
||||
* @param gson the gson instance whose configuration should by applied to a new GsonBuilder.
|
||||
*/
|
||||
GsonBuilder(Gson gson) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures Gson for custom serialization or deserialization. This method combines the
|
||||
* registration of an {@link TypeAdapter}, {@link InstanceCreator}, {@link JsonSerializer}, and a
|
||||
* {@link JsonDeserializer}. It is best used when a single object {@code typeAdapter} implements
|
||||
* all the required interfaces for custom serialization with Gson. If a type adapter was
|
||||
* previously registered for the specified {@code type}, it is overwritten.
|
||||
*
|
||||
* <p>This registers the type specified and no other types: you must manually register related
|
||||
* types! For example, applications registering {@code boolean.class} should also register {@code
|
||||
* Boolean.class}.
|
||||
*
|
||||
* @param type the type definition for the type adapter being registered
|
||||
* @param typeAdapter This object must implement at least one of the {@link TypeAdapter},
|
||||
* {@link InstanceCreator}, {@link JsonSerializer}, and a {@link JsonDeserializer} interfaces.
|
||||
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
||||
*/
|
||||
public GsonBuilder registerTypeAdapter(Type type, Object typeAdapter) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a factory for type adapters. Registering a factory is useful when the type
|
||||
* adapter needs to be configured based on the type of the field being processed. Gson
|
||||
* is designed to handle a large number of factories, so you should consider registering
|
||||
* them to be at par with registering an individual type adapter.
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
public GsonBuilder registerTypeAdapterFactory(TypeAdapterFactory factory) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures Gson for custom serialization or deserialization for an inheritance type hierarchy.
|
||||
* This method combines the registration of a {@link TypeAdapter}, {@link JsonSerializer} and
|
||||
* a {@link JsonDeserializer}. If a type adapter was previously registered for the specified
|
||||
* type hierarchy, it is overridden. If a type adapter is registered for a specific type in
|
||||
* the type hierarchy, it will be invoked instead of the one registered for the type hierarchy.
|
||||
*
|
||||
* @param baseType the class definition for the type adapter being registered for the base class
|
||||
* or interface
|
||||
* @param typeAdapter This object must implement at least one of {@link TypeAdapter},
|
||||
* {@link JsonSerializer} or {@link JsonDeserializer} interfaces.
|
||||
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
||||
* @since 1.7
|
||||
*/
|
||||
public GsonBuilder registerTypeHierarchyAdapter(Class<?> baseType, Object typeAdapter) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link Gson} instance based on the current configuration. This method is free of
|
||||
* side-effects to this {@code GsonBuilder} instance and hence can be called multiple times.
|
||||
*
|
||||
* @return an instance of Gson configured with the options currently set in this builder
|
||||
*/
|
||||
public Gson create() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
4
java/ql/test/stubs/gson-2.8.6/com/google/gson/JsonIOException.java
generated
Normal file
4
java/ql/test/stubs/gson-2.8.6/com/google/gson/JsonIOException.java
generated
Normal file
@@ -0,0 +1,4 @@
|
||||
package com.google.gson;
|
||||
|
||||
public final class JsonIOException extends RuntimeException {
|
||||
}
|
||||
4
java/ql/test/stubs/gson-2.8.6/com/google/gson/JsonSyntaxException.java
generated
Normal file
4
java/ql/test/stubs/gson-2.8.6/com/google/gson/JsonSyntaxException.java
generated
Normal file
@@ -0,0 +1,4 @@
|
||||
package com.google.gson;
|
||||
|
||||
public final class JsonSyntaxException extends RuntimeException {
|
||||
}
|
||||
130
java/ql/test/stubs/gson-2.8.6/com/google/gson/TypeAdapter.java
generated
Normal file
130
java/ql/test/stubs/gson-2.8.6/com/google/gson/TypeAdapter.java
generated
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.gson;
|
||||
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
|
||||
public abstract class TypeAdapter<T> {
|
||||
/**
|
||||
* Converts {@code value} to a JSON document and writes it to {@code out}.
|
||||
* Unlike Gson's similar {@link Gson#toJson(JsonElement, Appendable) toJson}
|
||||
* method, this write is strict. Create a {@link
|
||||
* JsonWriter#setLenient(boolean) lenient} {@code JsonWriter} and call
|
||||
* {@link #write(com.google.gson.stream.JsonWriter, Object)} for lenient
|
||||
* writing.
|
||||
*
|
||||
* @param value the Java object to convert. May be null.
|
||||
* @since 2.2
|
||||
*/
|
||||
public final void toJson(Writer out, T value) throws IOException {
|
||||
}
|
||||
|
||||
/**
|
||||
* This wrapper method is used to make a type adapter null tolerant. In general, a
|
||||
* type adapter is required to handle nulls in write and read methods. Here is how this
|
||||
* is typically done:<br>
|
||||
* <pre> {@code
|
||||
*
|
||||
* Gson gson = new GsonBuilder().registerTypeAdapter(Foo.class,
|
||||
* new TypeAdapter<Foo>() {
|
||||
* public Foo read(JsonReader in) throws IOException {
|
||||
* if (in.peek() == JsonToken.NULL) {
|
||||
* in.nextNull();
|
||||
* return null;
|
||||
* }
|
||||
* // read a Foo from in and return it
|
||||
* }
|
||||
* public void write(JsonWriter out, Foo src) throws IOException {
|
||||
* if (src == null) {
|
||||
* out.nullValue();
|
||||
* return;
|
||||
* }
|
||||
* // write src as JSON to out
|
||||
* }
|
||||
* }).create();
|
||||
* }</pre>
|
||||
* You can avoid this boilerplate handling of nulls by wrapping your type adapter with
|
||||
* this method. Here is how we will rewrite the above example:
|
||||
* <pre> {@code
|
||||
*
|
||||
* Gson gson = new GsonBuilder().registerTypeAdapter(Foo.class,
|
||||
* new TypeAdapter<Foo>() {
|
||||
* public Foo read(JsonReader in) throws IOException {
|
||||
* // read a Foo from in and return it
|
||||
* }
|
||||
* public void write(JsonWriter out, Foo src) throws IOException {
|
||||
* // write src as JSON to out
|
||||
* }
|
||||
* }.nullSafe()).create();
|
||||
* }</pre>
|
||||
* Note that we didn't need to check for nulls in our type adapter after we used nullSafe.
|
||||
*/
|
||||
public final TypeAdapter<T> nullSafe() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts {@code value} to a JSON document. Unlike Gson's similar {@link
|
||||
* Gson#toJson(Object) toJson} method, this write is strict. Create a {@link
|
||||
* JsonWriter#setLenient(boolean) lenient} {@code JsonWriter} and call
|
||||
* {@link #write(com.google.gson.stream.JsonWriter, Object)} for lenient
|
||||
* writing.
|
||||
*
|
||||
* @param value the Java object to convert. May be null.
|
||||
* @since 2.2
|
||||
*/
|
||||
public final String toJson(T value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads one JSON value (an array, object, string, number, boolean or null)
|
||||
* and converts it to a Java object. Returns the converted object.
|
||||
*
|
||||
* @return the converted Java object. May be null.
|
||||
*/
|
||||
public abstract T read(JsonReader in) throws IOException;
|
||||
|
||||
/**
|
||||
* Converts the JSON document in {@code in} to a Java object. Unlike Gson's
|
||||
* similar {@link Gson#fromJson(java.io.Reader, Class) fromJson} method, this
|
||||
* read is strict. Create a {@link JsonReader#setLenient(boolean) lenient}
|
||||
* {@code JsonReader} and call {@link #read(JsonReader)} for lenient reading.
|
||||
*
|
||||
* @return the converted Java object. May be null.
|
||||
* @since 2.2
|
||||
*/
|
||||
public final T fromJson(Reader in) throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the JSON document in {@code json} to a Java object. Unlike Gson's
|
||||
* similar {@link Gson#fromJson(String, Class) fromJson} method, this read is
|
||||
* strict. Create a {@link JsonReader#setLenient(boolean) lenient} {@code
|
||||
* JsonReader} and call {@link #read(JsonReader)} for lenient reading.
|
||||
*
|
||||
* @return the converted Java object. May be null.
|
||||
* @since 2.2
|
||||
*/
|
||||
public final T fromJson(String json) throws IOException {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
28
java/ql/test/stubs/gson-2.8.6/com/google/gson/TypeAdapterFactory.java
generated
Normal file
28
java/ql/test/stubs/gson-2.8.6/com/google/gson/TypeAdapterFactory.java
generated
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.gson;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
public interface TypeAdapterFactory {
|
||||
|
||||
/**
|
||||
* Returns a type adapter for {@code type}, or null if this factory doesn't
|
||||
* support {@code type}.
|
||||
*/
|
||||
<T> TypeAdapter<T> create(Gson gson, TypeToken<T> type);
|
||||
}
|
||||
50
java/ql/test/stubs/gson-2.8.6/com/google/gson/reflect/TypeToken.java
generated
Normal file
50
java/ql/test/stubs/gson-2.8.6/com/google/gson/reflect/TypeToken.java
generated
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.gson.reflect;
|
||||
|
||||
/**
|
||||
* Represents a generic type {@code T}. Java doesn't yet provide a way to
|
||||
* represent generic types, so this class does. Forces clients to create a
|
||||
* subclass of this class which enables retrieval the type information even at
|
||||
* runtime.
|
||||
*
|
||||
* <p>For example, to create a type literal for {@code List<String>}, you can
|
||||
* create an empty anonymous inner class:
|
||||
*
|
||||
* <p>
|
||||
* {@code TypeToken<List<String>> list = new TypeToken<List<String>>() {};}
|
||||
*
|
||||
* <p>This syntax cannot be used to create type literals that have wildcard
|
||||
* parameters, such as {@code Class<?>} or {@code List<? extends CharSequence>}.
|
||||
*
|
||||
* @author Bob Lee
|
||||
* @author Sven Mawson
|
||||
* @author Jesse Wilson
|
||||
*/
|
||||
public class TypeToken<T> {
|
||||
|
||||
/**
|
||||
* Constructs a new type literal. Derives represented class from type
|
||||
* parameter.
|
||||
*
|
||||
* <p>Clients create an empty anonymous subclass. Doing so embeds the type
|
||||
* parameter in the anonymous class's type hierarchy so we can reconstitute it
|
||||
* at runtime despite erasure.
|
||||
*/
|
||||
protected TypeToken() {
|
||||
}
|
||||
}
|
||||
66
java/ql/test/stubs/gson-2.8.6/com/google/gson/stream/JsonReader.java
generated
Normal file
66
java/ql/test/stubs/gson-2.8.6/com/google/gson/stream/JsonReader.java
generated
Normal file
@@ -0,0 +1,66 @@
|
||||
package com.google.gson.stream;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
|
||||
public class JsonReader implements Closeable {
|
||||
public JsonReader(Reader in) {
|
||||
}
|
||||
|
||||
public final void setLenient(boolean lenient) {
|
||||
}
|
||||
|
||||
public final boolean isLenient() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void beginArray() throws IOException {
|
||||
}
|
||||
|
||||
public void endArray() throws IOException {
|
||||
}
|
||||
|
||||
public void beginObject() throws IOException {
|
||||
}
|
||||
|
||||
public void endObject() throws IOException {
|
||||
}
|
||||
|
||||
public boolean hasNext() throws IOException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String nextName() throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String nextString() throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean nextBoolean() throws IOException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void nextNull() throws IOException {
|
||||
}
|
||||
|
||||
public double nextDouble() throws IOException {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public long nextLong() throws IOException {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int nextInt() throws IOException {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
}
|
||||
|
||||
public void skipValue() throws IOException {
|
||||
}
|
||||
}
|
||||
178
java/ql/test/stubs/gson-2.8.6/com/google/gson/typeadapters/RuntimeTypeAdapterFactory.java
generated
Normal file
178
java/ql/test/stubs/gson-2.8.6/com/google/gson/typeadapters/RuntimeTypeAdapterFactory.java
generated
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.gson.typeadapters;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.TypeAdapterFactory;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
/**
|
||||
* Adapts values whose runtime type may differ from their declaration type. This
|
||||
* is necessary when a field's type is not the same type that GSON should create
|
||||
* when deserializing that field. For example, consider these types:
|
||||
* <pre> {@code
|
||||
* abstract class Shape {
|
||||
* int x;
|
||||
* int y;
|
||||
* }
|
||||
* class Circle extends Shape {
|
||||
* int radius;
|
||||
* }
|
||||
* class Rectangle extends Shape {
|
||||
* int width;
|
||||
* int height;
|
||||
* }
|
||||
* class Diamond extends Shape {
|
||||
* int width;
|
||||
* int height;
|
||||
* }
|
||||
* class Drawing {
|
||||
* Shape bottomShape;
|
||||
* Shape topShape;
|
||||
* }
|
||||
* }</pre>
|
||||
* <p>Without additional type information, the serialized JSON is ambiguous. Is
|
||||
* the bottom shape in this drawing a rectangle or a diamond? <pre> {@code
|
||||
* {
|
||||
* "bottomShape": {
|
||||
* "width": 10,
|
||||
* "height": 5,
|
||||
* "x": 0,
|
||||
* "y": 0
|
||||
* },
|
||||
* "topShape": {
|
||||
* "radius": 2,
|
||||
* "x": 4,
|
||||
* "y": 1
|
||||
* }
|
||||
* }}</pre>
|
||||
* This class addresses this problem by adding type information to the
|
||||
* serialized JSON and honoring that type information when the JSON is
|
||||
* deserialized: <pre> {@code
|
||||
* {
|
||||
* "bottomShape": {
|
||||
* "type": "Diamond",
|
||||
* "width": 10,
|
||||
* "height": 5,
|
||||
* "x": 0,
|
||||
* "y": 0
|
||||
* },
|
||||
* "topShape": {
|
||||
* "type": "Circle",
|
||||
* "radius": 2,
|
||||
* "x": 4,
|
||||
* "y": 1
|
||||
* }
|
||||
* }}</pre>
|
||||
* Both the type field name ({@code "type"}) and the type labels ({@code
|
||||
* "Rectangle"}) are configurable.
|
||||
*
|
||||
* <h3>Registering Types</h3>
|
||||
* Create a {@code RuntimeTypeAdapterFactory} by passing the base type and type field
|
||||
* name to the {@link #of} factory method. If you don't supply an explicit type
|
||||
* field name, {@code "type"} will be used. <pre> {@code
|
||||
* RuntimeTypeAdapterFactory<Shape> shapeAdapterFactory
|
||||
* = RuntimeTypeAdapterFactory.of(Shape.class, "type");
|
||||
* }</pre>
|
||||
* Next register all of your subtypes. Every subtype must be explicitly
|
||||
* registered. This protects your application from injection attacks. If you
|
||||
* don't supply an explicit type label, the type's simple name will be used.
|
||||
* <pre> {@code
|
||||
* shapeAdapterFactory.registerSubtype(Rectangle.class, "Rectangle");
|
||||
* shapeAdapterFactory.registerSubtype(Circle.class, "Circle");
|
||||
* shapeAdapterFactory.registerSubtype(Diamond.class, "Diamond");
|
||||
* }</pre>
|
||||
* Finally, register the type adapter factory in your application's GSON builder:
|
||||
* <pre> {@code
|
||||
* Gson gson = new GsonBuilder()
|
||||
* .registerTypeAdapterFactory(shapeAdapterFactory)
|
||||
* .create();
|
||||
* }</pre>
|
||||
* Like {@code GsonBuilder}, this API supports chaining: <pre> {@code
|
||||
* RuntimeTypeAdapterFactory<Shape> shapeAdapterFactory = RuntimeTypeAdapterFactory.of(Shape.class)
|
||||
* .registerSubtype(Rectangle.class)
|
||||
* .registerSubtype(Circle.class)
|
||||
* .registerSubtype(Diamond.class);
|
||||
* }</pre>
|
||||
*
|
||||
* <h3>Serialization and deserialization</h3>
|
||||
* In order to serialize and deserialize a polymorphic object,
|
||||
* you must specify the base type explicitly.
|
||||
* <pre> {@code
|
||||
* Diamond diamond = new Diamond();
|
||||
* String json = gson.toJson(diamond, Shape.class);
|
||||
* }</pre>
|
||||
* And then:
|
||||
* <pre> {@code
|
||||
* Shape shape = gson.fromJson(json, Shape.class);
|
||||
* }</pre>
|
||||
*/
|
||||
public final class RuntimeTypeAdapterFactory<T> implements TypeAdapterFactory {
|
||||
/**
|
||||
* Creates a new runtime type adapter using for {@code baseType} using {@code
|
||||
* typeFieldName} as the type field name. Type field names are case sensitive.
|
||||
* {@code maintainType} flag decide if the type will be stored in pojo or not.
|
||||
*/
|
||||
public static <T> RuntimeTypeAdapterFactory<T> of(Class<T> baseType, String typeFieldName, boolean maintainType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new runtime type adapter using for {@code baseType} using {@code
|
||||
* typeFieldName} as the type field name. Type field names are case sensitive.
|
||||
*/
|
||||
public static <T> RuntimeTypeAdapterFactory<T> of(Class<T> baseType, String typeFieldName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new runtime type adapter for {@code baseType} using {@code "type"} as
|
||||
* the type field name.
|
||||
*/
|
||||
public static <T> RuntimeTypeAdapterFactory<T> of(Class<T> baseType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers {@code type} identified by {@code label}. Labels are case
|
||||
* sensitive.
|
||||
*
|
||||
* @throws IllegalArgumentException if either {@code type} or {@code label}
|
||||
* have already been registered on this type adapter.
|
||||
*/
|
||||
public RuntimeTypeAdapterFactory<T> registerSubtype(Class<? extends T> type, String label) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers {@code type} identified by its {@link Class#getSimpleName simple
|
||||
* name}. Labels are case sensitive.
|
||||
*
|
||||
* @throws IllegalArgumentException if either {@code type} or its simple name
|
||||
* have already been registered on this type adapter.
|
||||
*/
|
||||
public RuntimeTypeAdapterFactory<T> registerSubtype(Class<? extends T> type) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public <R> TypeAdapter<R> create(Gson gson, TypeToken<R> type) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user