gson-compile/gson-compile-processor/src/main/java/io/gitlab/jfronny/gson/compile/processor/adapter/AdapterAdapter.java

70 lines
3.0 KiB
Java

package io.gitlab.jfronny.gson.compile.processor.adapter;
import com.squareup.javapoet.*;
import io.gitlab.jfronny.gson.compile.processor.Cl;
import io.gitlab.jfronny.gson.compile.processor.core.TypeHelper;
import javax.lang.model.type.TypeMirror;
import java.lang.reflect.ParameterizedType;
import java.util.Iterator;
import java.util.List;
public abstract class AdapterAdapter<T extends AdapterAdapter<T>.Hydrated> extends Adapter<T> {
public abstract class Hydrated extends Adapter<T>.Hydrated {
@Override
public void generateWrite(Runnable writeGet) {
code.add("$L.write(", getAdapter());
writeGet.run();
code.add(", writer);\n");
}
@Override
public void generateRead() {
code.add("$L.read(reader)", getAdapter());
}
private String getAdapter() {
for (FieldSpec spec : klazz.fieldSpecs) {
if (spec.name.equals(adapterName)) return adapterName;
}
return createAdapter(adapterName);
}
protected abstract String createAdapter(String name);
protected void appendFieldTypeToken(boolean allowClassType) {
TypeName typeName = TypeName.get(type);
if (TypeHelper.isComplexType(type, typeUtils)) {
TypeName typeTokenType = ParameterizedTypeName.get(Cl.TYPE_TOKEN, typeName);
List<? extends TypeMirror> typeParams = TypeHelper.getGenericTypes(type);
if (typeParams.isEmpty()) {
code.add("new $T() {}", typeTokenType);
} else {
code.add("($T) $T.getParameterized($T.class, ", typeTokenType, Cl.TYPE_TOKEN, typeUtils.erasure(type));
for (Iterator<? extends TypeMirror> iterator = typeParams.iterator(); iterator.hasNext(); ) {
TypeMirror typeParam = iterator.next();
int typeIndex = typeVariables.indexOf(TypeVariableName.get(typeParam.toString()));
code.add("(($T)typeToken.getType()).getActualTypeArguments()[$L]", ParameterizedType.class, typeIndex);
if (iterator.hasNext()) {
code.add(", ");
}
}
code.add(")");
}
} else if (TypeHelper.isGenericType(type)) {
TypeName typeTokenType = ParameterizedTypeName.get(Cl.TYPE_TOKEN, typeName);
int typeIndex = typeVariables.indexOf(TypeVariableName.get(type.toString()));
code.add("($T) $T.get((($T)typeToken.getType()).getActualTypeArguments()[$L])",
typeTokenType, Cl.TYPE_TOKEN, ParameterizedType.class, typeIndex);
} else {
if (allowClassType) {
code.add("$T.class", typeName);
} else {
code.add("TypeToken.get($T.class)", typeName);
}
}
}
}
}