Updated older annotation processors
This commit is contained in:
@@ -1,17 +1,14 @@
|
|||||||
package mindustry.annotations.impl;
|
package mindustry.annotations.impl;
|
||||||
|
|
||||||
|
import arc.struct.*;
|
||||||
import com.squareup.javapoet.*;
|
import com.squareup.javapoet.*;
|
||||||
|
import mindustry.annotations.Annotations.*;
|
||||||
import mindustry.annotations.*;
|
import mindustry.annotations.*;
|
||||||
import mindustry.annotations.Annotations.Struct;
|
import mindustry.annotations.util.*;
|
||||||
import mindustry.annotations.Annotations.StructField;
|
|
||||||
|
|
||||||
import javax.annotation.processing.*;
|
import javax.annotation.processing.*;
|
||||||
import javax.lang.model.element.*;
|
import javax.lang.model.element.*;
|
||||||
import javax.lang.model.type.TypeKind;
|
import javax.lang.model.type.*;
|
||||||
import javax.lang.model.util.ElementFilter;
|
|
||||||
import javax.tools.Diagnostic.Kind;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates ""value types"" classes that are packed into integer primitives of the most aproppriate size.
|
* Generates ""value types"" classes that are packed into integer primitives of the most aproppriate size.
|
||||||
@@ -24,28 +21,28 @@ public class StructProcess extends BaseProcessor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(RoundEnvironment env) throws Exception{
|
public void process(RoundEnvironment env) throws Exception{
|
||||||
Set<TypeElement> elements = ElementFilter.typesIn(env.getElementsAnnotatedWith(Struct.class));
|
Seq<Stype> elements = types(Struct.class);
|
||||||
|
|
||||||
for(TypeElement elem : elements){
|
for(Stype elem : elements){
|
||||||
|
|
||||||
if(!elem.getSimpleName().toString().endsWith("Struct")){
|
if(!elem.name().endsWith("Struct")){
|
||||||
BaseProcessor.err("All classes annotated with @Struct must have their class names end in 'Struct'.", elem);
|
err("All classes annotated with @Struct must have their class names end in 'Struct'.", elem);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
String structName = elem.getSimpleName().toString().substring(0, elem.getSimpleName().toString().length() - "Struct".length());
|
String structName = elem.name().substring(0, elem.name().length() - "Struct".length());
|
||||||
String structParam = structName.toLowerCase();
|
String structParam = structName.toLowerCase();
|
||||||
|
|
||||||
TypeSpec.Builder classBuilder = TypeSpec.classBuilder(structName)
|
TypeSpec.Builder classBuilder = TypeSpec.classBuilder(structName)
|
||||||
.addModifiers(Modifier.FINAL, Modifier.PUBLIC);
|
.addModifiers(Modifier.FINAL, Modifier.PUBLIC);
|
||||||
|
|
||||||
try{
|
try{
|
||||||
List<VariableElement> variables = ElementFilter.fieldsIn(elem.getEnclosedElements());
|
Seq<Svar> variables = elem.fields();
|
||||||
int structSize = variables.stream().mapToInt(StructProcess::varSize).sum();
|
int structSize = variables.mapInt(StructProcess::varSize).sum();
|
||||||
int structTotalSize = (structSize <= 8 ? 8 : structSize <= 16 ? 16 : structSize <= 32 ? 32 : 64);
|
int structTotalSize = (structSize <= 8 ? 8 : structSize <= 16 ? 16 : structSize <= 32 ? 32 : 64);
|
||||||
|
|
||||||
if(variables.size() == 0){
|
if(variables.size == 0){
|
||||||
BaseProcessor.err("making a struct with no fields is utterly pointles.", elem);
|
err("making a struct with no fields is utterly pointles.", elem);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,21 +59,21 @@ public class StructProcess extends BaseProcessor{
|
|||||||
doc.append("Bits used: ").append(structSize).append(" / ").append(structTotalSize).append("\n");
|
doc.append("Bits used: ").append(structSize).append(" / ").append(structTotalSize).append("\n");
|
||||||
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
for(VariableElement var : variables){
|
for(Svar var : variables){
|
||||||
int size = varSize(var);
|
int size = varSize(var);
|
||||||
TypeName varType = TypeName.get(var.asType());
|
TypeName varType = var.tname();
|
||||||
String varName = var.getSimpleName().toString();
|
String varName = var.name();
|
||||||
|
|
||||||
//add val param to constructor
|
//add val param to constructor
|
||||||
constructor.addParameter(varType, varName);
|
constructor.addParameter(varType, varName);
|
||||||
|
|
||||||
//[get] field(structType) : fieldType
|
//[get] field(structType) : fieldType
|
||||||
MethodSpec.Builder getter = MethodSpec.methodBuilder(var.getSimpleName().toString())
|
MethodSpec.Builder getter = MethodSpec.methodBuilder(var.name().toString())
|
||||||
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
|
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
|
||||||
.returns(varType)
|
.returns(varType)
|
||||||
.addParameter(structType, structParam);
|
.addParameter(structType, structParam);
|
||||||
//[set] field(structType, fieldType) : structType
|
//[set] field(structType, fieldType) : structType
|
||||||
MethodSpec.Builder setter = MethodSpec.methodBuilder(var.getSimpleName().toString())
|
MethodSpec.Builder setter = MethodSpec.methodBuilder(var.name().toString())
|
||||||
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
|
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
|
||||||
.returns(structType)
|
.returns(structType)
|
||||||
.addParameter(structType, structParam).addParameter(varType, "value");
|
.addParameter(structType, structParam).addParameter(varType, "value");
|
||||||
@@ -133,7 +130,7 @@ public class StructProcess extends BaseProcessor{
|
|||||||
JavaFile.builder(packageName, classBuilder.build()).build().writeTo(BaseProcessor.filer);
|
JavaFile.builder(packageName, classBuilder.build()).build().writeTo(BaseProcessor.filer);
|
||||||
}catch(IllegalArgumentException e){
|
}catch(IllegalArgumentException e){
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
BaseProcessor.err(e.getMessage(), elem);
|
err(e.getMessage(), elem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,21 +151,21 @@ public class StructProcess extends BaseProcessor{
|
|||||||
return "0b" + builder.reverse().toString() + "L";
|
return "0b" + builder.reverse().toString() + "L";
|
||||||
}
|
}
|
||||||
|
|
||||||
static int varSize(VariableElement var) throws IllegalArgumentException{
|
static int varSize(Svar var) throws IllegalArgumentException{
|
||||||
if(!var.asType().getKind().isPrimitive()){
|
if(!var.mirror().getKind().isPrimitive()){
|
||||||
throw new IllegalArgumentException("All struct fields must be primitives: " + var);
|
throw new IllegalArgumentException("All struct fields must be primitives: " + var);
|
||||||
}
|
}
|
||||||
|
|
||||||
StructField an = var.getAnnotation(StructField.class);
|
StructField an = var.annotation(StructField.class);
|
||||||
if(var.asType().getKind() == TypeKind.BOOLEAN && an != null && an.value() != 1){
|
if(var.mirror().getKind() == TypeKind.BOOLEAN && an != null && an.value() != 1){
|
||||||
throw new IllegalArgumentException("Booleans can only be one bit long... why would you do this?");
|
throw new IllegalArgumentException("Booleans can only be one bit long... why would you do this?");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(var.asType().getKind() == TypeKind.FLOAT && an != null && an.value() != 32){
|
if(var.mirror().getKind() == TypeKind.FLOAT && an != null && an.value() != 32){
|
||||||
throw new IllegalArgumentException("Float size can't be changed. Very sad.");
|
throw new IllegalArgumentException("Float size can't be changed. Very sad.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return an == null ? typeSize(var.asType().getKind()) : an.value();
|
return an == null ? typeSize(var.mirror().getKind()) : an.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
static Class<?> typeForSize(int size) throws IllegalArgumentException{
|
static Class<?> typeForSize(int size) throws IllegalArgumentException{
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
package mindustry.annotations.remote;
|
package mindustry.annotations.remote;
|
||||||
|
|
||||||
|
import arc.struct.*;
|
||||||
import com.squareup.javapoet.*;
|
import com.squareup.javapoet.*;
|
||||||
import mindustry.annotations.*;
|
|
||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
|
import mindustry.annotations.*;
|
||||||
import mindustry.annotations.util.*;
|
import mindustry.annotations.util.*;
|
||||||
import mindustry.annotations.util.TypeIOResolver.*;
|
import mindustry.annotations.util.TypeIOResolver.*;
|
||||||
|
|
||||||
import javax.annotation.processing.*;
|
import javax.annotation.processing.*;
|
||||||
import javax.lang.model.element.*;
|
import javax.lang.model.element.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.*;
|
|
||||||
|
|
||||||
|
|
||||||
/** The annotation processor for generating remote method call code. */
|
/** The annotation processor for generating remote method call code. */
|
||||||
@@ -33,13 +33,13 @@ public class RemoteProcess extends BaseProcessor{
|
|||||||
//class serializers
|
//class serializers
|
||||||
private ClassSerializer serializer;
|
private ClassSerializer serializer;
|
||||||
//all elements with the Remote annotation
|
//all elements with the Remote annotation
|
||||||
private Set<? extends Element> elements;
|
private Seq<Smethod> elements;
|
||||||
//map of all classes to generate by name
|
//map of all classes to generate by name
|
||||||
private HashMap<String, ClassEntry> classMap;
|
private HashMap<String, ClassEntry> classMap;
|
||||||
//list of all method entries
|
//list of all method entries
|
||||||
private ArrayList<MethodEntry> methods;
|
private Seq<MethodEntry> methods;
|
||||||
//list of all method entries
|
//list of all method entries
|
||||||
private ArrayList<ClassEntry> classes;
|
private Seq<ClassEntry> classes;
|
||||||
|
|
||||||
{
|
{
|
||||||
rounds = 2;
|
rounds = 2;
|
||||||
@@ -54,23 +54,23 @@ public class RemoteProcess extends BaseProcessor{
|
|||||||
//last method ID used
|
//last method ID used
|
||||||
int lastMethodID = 0;
|
int lastMethodID = 0;
|
||||||
//find all elements with the Remote annotation
|
//find all elements with the Remote annotation
|
||||||
elements = roundEnv.getElementsAnnotatedWith(Remote.class);
|
elements = methods(Remote.class);
|
||||||
//map of all classes to generate by name
|
//map of all classes to generate by name
|
||||||
classMap = new HashMap<>();
|
classMap = new HashMap<>();
|
||||||
//list of all method entries
|
//list of all method entries
|
||||||
methods = new ArrayList<>();
|
methods = new Seq<>();
|
||||||
//list of all method entries
|
//list of all method entries
|
||||||
classes = new ArrayList<>();
|
classes = new Seq<>();
|
||||||
|
|
||||||
List<Element> orderedElements = new ArrayList<>(elements);
|
Seq<Smethod> orderedElements = elements.copy();
|
||||||
orderedElements.sort(Comparator.comparing(Object::toString));
|
orderedElements.sortComparing(Object::toString);
|
||||||
|
|
||||||
//create methods
|
//create methods
|
||||||
for(Element element : orderedElements){
|
for(Smethod element : orderedElements){
|
||||||
Remote annotation = element.getAnnotation(Remote.class);
|
Remote annotation = element.annotation(Remote.class);
|
||||||
|
|
||||||
//check for static
|
//check for static
|
||||||
if(!element.getModifiers().contains(Modifier.STATIC) || !element.getModifiers().contains(Modifier.PUBLIC)){
|
if(!element.is(Modifier.STATIC) || !element.is(Modifier.PUBLIC)){
|
||||||
err("All @Remote methods must be public and static: ", element);
|
err("All @Remote methods must be public and static: ", element);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,8 +89,8 @@ public class RemoteProcess extends BaseProcessor{
|
|||||||
ClassEntry entry = classMap.get(callLocation);
|
ClassEntry entry = classMap.get(callLocation);
|
||||||
|
|
||||||
//create and add entry
|
//create and add entry
|
||||||
MethodEntry method = new MethodEntry(entry.name, BaseProcessor.getMethodName(element), annotation.targets(), annotation.variants(),
|
MethodEntry method = new MethodEntry(entry.name, BaseProcessor.getMethodName(element.e), annotation.targets(), annotation.variants(),
|
||||||
annotation.called(), annotation.unreliable(), annotation.forward(), lastMethodID++, (ExecutableElement)element, annotation.priority());
|
annotation.called(), annotation.unreliable(), annotation.forward(), lastMethodID++, element.e, annotation.priority());
|
||||||
|
|
||||||
entry.methods.add(method);
|
entry.methods.add(method);
|
||||||
methods.add(method);
|
methods.add(method);
|
||||||
@@ -105,15 +105,15 @@ public class RemoteProcess extends BaseProcessor{
|
|||||||
RemoteReadGenerator readgen = new RemoteReadGenerator(serializer);
|
RemoteReadGenerator readgen = new RemoteReadGenerator(serializer);
|
||||||
|
|
||||||
//generate server readers
|
//generate server readers
|
||||||
readgen.generateFor(methods.stream().filter(method -> method.where.isClient).collect(Collectors.toList()), readServerName, packageName, true);
|
readgen.generateFor(methods.select(method -> method.where.isClient), readServerName, packageName, true);
|
||||||
//generate client readers
|
//generate client readers
|
||||||
readgen.generateFor(methods.stream().filter(method -> method.where.isServer).collect(Collectors.toList()), readClientName, packageName, false);
|
readgen.generateFor(methods.select(method -> method.where.isServer), readClientName, packageName, false);
|
||||||
|
|
||||||
//create class for storing unique method hash
|
//create class for storing unique method hash
|
||||||
TypeSpec.Builder hashBuilder = TypeSpec.classBuilder("MethodHash").addModifiers(Modifier.PUBLIC);
|
TypeSpec.Builder hashBuilder = TypeSpec.classBuilder("MethodHash").addModifiers(Modifier.PUBLIC);
|
||||||
hashBuilder.addJavadoc(autogenWarning);
|
hashBuilder.addJavadoc(autogenWarning);
|
||||||
hashBuilder.addField(FieldSpec.builder(int.class, "HASH", Modifier.STATIC, Modifier.PUBLIC, Modifier.FINAL)
|
hashBuilder.addField(FieldSpec.builder(int.class, "HASH", Modifier.STATIC, Modifier.PUBLIC, Modifier.FINAL)
|
||||||
.initializer("$1L", Objects.hash(methods)).build());
|
.initializer("$1L", Arrays.hashCode(methods.map(m -> m.element).toArray())).build());
|
||||||
|
|
||||||
//build and write resulting hash class
|
//build and write resulting hash class
|
||||||
TypeSpec spec = hashBuilder.build();
|
TypeSpec spec = hashBuilder.build();
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package mindustry.annotations.remote;
|
package mindustry.annotations.remote;
|
||||||
|
|
||||||
|
import arc.struct.*;
|
||||||
import arc.util.io.*;
|
import arc.util.io.*;
|
||||||
import com.squareup.javapoet.*;
|
import com.squareup.javapoet.*;
|
||||||
import mindustry.annotations.*;
|
import mindustry.annotations.*;
|
||||||
import mindustry.annotations.util.TypeIOResolver.*;
|
import mindustry.annotations.util.TypeIOResolver.*;
|
||||||
|
|
||||||
import javax.lang.model.element.*;
|
import javax.lang.model.element.*;
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
/** Generates code for reading remote invoke packets on the client and server. */
|
/** Generates code for reading remote invoke packets on the client and server. */
|
||||||
public class RemoteReadGenerator{
|
public class RemoteReadGenerator{
|
||||||
@@ -24,7 +24,7 @@ public class RemoteReadGenerator{
|
|||||||
* @param packageName Full target package name.
|
* @param packageName Full target package name.
|
||||||
* @param needsPlayer Whether this read method requires a reference to the player sender.
|
* @param needsPlayer Whether this read method requires a reference to the player sender.
|
||||||
*/
|
*/
|
||||||
public void generateFor(List<MethodEntry> entries, String className, String packageName, boolean needsPlayer) throws Exception{
|
public void generateFor(Seq<MethodEntry> entries, String className, String packageName, boolean needsPlayer) throws Exception{
|
||||||
|
|
||||||
TypeSpec.Builder classBuilder = TypeSpec.classBuilder(className).addModifiers(Modifier.PUBLIC);
|
TypeSpec.Builder classBuilder = TypeSpec.classBuilder(className).addModifiers(Modifier.PUBLIC);
|
||||||
classBuilder.addJavadoc(RemoteProcess.autogenWarning);
|
classBuilder.addJavadoc(RemoteProcess.autogenWarning);
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import mindustry.annotations.util.TypeIOResolver.*;
|
|||||||
|
|
||||||
import javax.lang.model.element.*;
|
import javax.lang.model.element.*;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
/** Generates code for writing remote invoke packets on the client and server. */
|
/** Generates code for writing remote invoke packets on the client and server. */
|
||||||
public class RemoteWriteGenerator{
|
public class RemoteWriteGenerator{
|
||||||
@@ -21,7 +20,7 @@ public class RemoteWriteGenerator{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Generates all classes in this list. */
|
/** Generates all classes in this list. */
|
||||||
public void generateFor(List<ClassEntry> entries, String packageName) throws IOException{
|
public void generateFor(Seq<ClassEntry> entries, String packageName) throws IOException{
|
||||||
|
|
||||||
for(ClassEntry entry : entries){
|
for(ClassEntry entry : entries){
|
||||||
//create builder
|
//create builder
|
||||||
|
|||||||
Reference in New Issue
Block a user