Readme, support for enforcing no reflection

This commit is contained in:
Johannes Frohnmeyer 2022-11-01 09:55:08 +01:00
parent e2f59601c0
commit b3cac10554
Signed by: Johannes
GPG Key ID: E76429612C2929F4
5 changed files with 39 additions and 12 deletions

28
README.md Normal file
View File

@ -0,0 +1,28 @@
# Gson-Compile
A java annotation processor implementing automated type adapter generation for gson-comments.
The goal of this AP is to
- Support common features such as getters, setters, fields, constructors
- Support modern language features such as records
- Support json5 through gson-comments
- Be compile-time where possible (ideally compatible with proguard)
## Currently supported
- Primitive types
- Adapter generation
- Utility methods
- Strict no-reflection enforcement via `-AgsonCompileNoReflect`
## TODO
- Arrays
- Comments
- Nested serializable types
- Date
- Enums
- Lists
- Maps
- Queues
- Records
- Support for nested types from libraries
- Sets
- Static classes (for configs)
- GPrefer to bypass builder/constructor recovery

View File

@ -13,7 +13,3 @@ repositories {
dependencies { dependencies {
api("io.gitlab.jfronny:commons-gson:2022.10.22+20-29-33") api("io.gitlab.jfronny:commons-gson:2022.10.22+20-29-33")
} }
tasks.getByName<Test>("test") {
useJUnitPlatform()
}

View File

@ -17,3 +17,6 @@ dependencies {
implementation(project(":gson-compile-core")) implementation(project(":gson-compile-core"))
} }
tasks.withType<JavaCompile> {
options.compilerArgs.add("-AgsonCompileNoReflect")
}

View File

@ -1,13 +1,10 @@
package io.gitlab.jfronny.gson; package io.gitlab.jfronny.gson;
import io.gitlab.jfronny.gson.compile.annotations.GSerializable; import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
import io.gitlab.jfronny.gson.stream.JsonReader;
import io.gitlab.jfronny.gson.stream.JsonWriter;
public class Main { public class Main {
public static void main(String[] args) { public static void main(String[] args) {
System.out.println("Hello world!"); System.out.println("Hello world!");
//JsonReader
} }
@GSerializable(generateAdapter = true) @GSerializable(generateAdapter = true)

View File

@ -20,9 +20,9 @@ import java.lang.reflect.ParameterizedType;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
//TODO support for records
@SupportedSourceVersion(SourceVersion.RELEASE_17) @SupportedSourceVersion(SourceVersion.RELEASE_17)
@SupportedAnnotationTypes2({GSerializable.class}) @SupportedAnnotationTypes2({GSerializable.class})
@SupportedOptions({"gsonCompileNoReflect"})
public class GsonCompileProcessor extends AbstractProcessor2 { public class GsonCompileProcessor extends AbstractProcessor2 {
private Messager message; private Messager message;
private Types typeUtils; private Types typeUtils;
@ -30,6 +30,7 @@ public class GsonCompileProcessor extends AbstractProcessor2 {
private Set<ClassName> seen; private Set<ClassName> seen;
private ValueCreator valueCreator; private ValueCreator valueCreator;
private Elements elements; private Elements elements;
private Map<String, String> options;
@Override @Override
public synchronized void init(ProcessingEnvironment processingEnv) { public synchronized void init(ProcessingEnvironment processingEnv) {
@ -38,6 +39,7 @@ public class GsonCompileProcessor extends AbstractProcessor2 {
filer = processingEnv.getFiler(); filer = processingEnv.getFiler();
typeUtils = processingEnv.getTypeUtils(); typeUtils = processingEnv.getTypeUtils();
elements = processingEnv.getElementUtils(); elements = processingEnv.getElementUtils();
options = processingEnv.getOptions();
seen = new LinkedHashSet<>(); seen = new LinkedHashSet<>();
valueCreator = new ValueCreator(processingEnv); valueCreator = new ValueCreator(processingEnv);
} }
@ -188,9 +190,9 @@ public class GsonCompileProcessor extends AbstractProcessor2 {
.addException(IOException.class) .addException(IOException.class)
.returns(classType) .returns(classType)
.addCode(""" .addCode("""
try ($1T reader = new $1T(in)) { try ($T reader = $T.HOLDER.getGson().newJsonReader(in)) {
return read(reader); return read(reader);
}""", Const.GSON_READER) }""", Const.GSON_READER, Const.CCORE)
.build() .build()
); );
@ -227,9 +229,9 @@ public class GsonCompileProcessor extends AbstractProcessor2 {
.addParameter(classType, "value") .addParameter(classType, "value")
.addException(IOException.class) .addException(IOException.class)
.addCode(""" .addCode("""
try ($1T writer = new $1T(out)) { try ($T writer = $T.HOLDER.getGson().newJsonWriter(out)) {
write(writer, value); write(writer, value);
}""", Const.GSON_WRITER) }""", Const.GSON_WRITER, Const.CCORE)
.build() .build()
); );
@ -437,6 +439,7 @@ public class GsonCompileProcessor extends AbstractProcessor2 {
); );
} else message.printMessage(Diagnostic.Kind.ERROR, "@JsonAdapter value must by TypeAdapter or TypeAdapterFactory reference.", prop.getElement()); } else message.printMessage(Diagnostic.Kind.ERROR, "@JsonAdapter value must by TypeAdapter or TypeAdapterFactory reference.", prop.getElement());
} else { } else {
message.printMessage(options.containsKey("gsonCompileNoReflect") ? Diagnostic.Kind.ERROR : Diagnostic.Kind.WARNING, "Falling back to adapter detection for unsupported type " + prop.getType(), prop.getElement());
//TODO handle known custom type adapters and return proper static class //TODO handle known custom type adapters and return proper static class
TypeName typeAdapterType = ParameterizedTypeName.get(Const.TYPE_ADAPTER, TypeName.get(prop.getType()).box()); TypeName typeAdapterType = ParameterizedTypeName.get(Const.TYPE_ADAPTER, TypeName.get(prop.getType()).box());
CodeBlock.Builder block = CodeBlock.builder(); CodeBlock.Builder block = CodeBlock.builder();