Annotation processor cleanup
This commit is contained in:
@@ -14,43 +14,20 @@ import javax.tools.Diagnostic.*;
|
|||||||
import javax.tools.*;
|
import javax.tools.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@SupportedSourceVersion(SourceVersion.RELEASE_8)
|
|
||||||
@SupportedAnnotationTypes("mindustry.annotations.Annotations.StyleDefaults")
|
@SupportedAnnotationTypes("mindustry.annotations.Annotations.StyleDefaults")
|
||||||
public class AssetsAnnotationProcessor extends AbstractProcessor{
|
public class AssetsAnnotationProcessor extends BaseProcessor{
|
||||||
/** Name of the base package to put all the generated classes. */
|
|
||||||
private static final String packageName = "mindustry.gen";
|
|
||||||
private String path;
|
private String path;
|
||||||
private int round;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void init(ProcessingEnvironment processingEnv){
|
public void process(RoundEnvironment env) throws Exception{
|
||||||
super.init(processingEnv);
|
path = Fi.get(Utils.filer.createResource(StandardLocation.CLASS_OUTPUT, "no", "no")
|
||||||
//put all relevant utils into utils class
|
.toUri().toURL().toString().substring(System.getProperty("os.name").contains("Windows") ? 6 : "file:".length()))
|
||||||
Utils.typeUtils = processingEnv.getTypeUtils();
|
.parent().parent().parent().parent().parent().parent().toString();
|
||||||
Utils.elementUtils = processingEnv.getElementUtils();
|
path = path.replace("%20", " ");
|
||||||
Utils.filer = processingEnv.getFiler();
|
|
||||||
Utils.messager = processingEnv.getMessager();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
processSounds("Sounds", path + "/assets/sounds", "arc.audio.Sound");
|
||||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv){
|
processSounds("Musics", path + "/assets/music", "arc.audio.Music");
|
||||||
if(round++ != 0) return false; //only process 1 round
|
processUI(env.getElementsAnnotatedWith(StyleDefaults.class));
|
||||||
|
|
||||||
try{
|
|
||||||
path = Fi.get(Utils.filer.createResource(StandardLocation.CLASS_OUTPUT, "no", "no")
|
|
||||||
.toUri().toURL().toString().substring(System.getProperty("os.name").contains("Windows") ? 6 : "file:".length()))
|
|
||||||
.parent().parent().parent().parent().parent().parent().toString();
|
|
||||||
path = path.replace("%20", " ");
|
|
||||||
|
|
||||||
processSounds("Sounds", path + "/assets/sounds", "arc.audio.Sound");
|
|
||||||
processSounds("Musics", path + "/assets/music", "arc.audio.Music");
|
|
||||||
processUI(roundEnv.getElementsAnnotatedWith(StyleDefaults.class));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}catch(Exception e){
|
|
||||||
e.printStackTrace();
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void processUI(Set<? extends Element> elements) throws Exception{
|
void processUI(Set<? extends Element> elements) throws Exception{
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package mindustry.annotations;
|
||||||
|
|
||||||
|
import javax.annotation.processing.*;
|
||||||
|
import javax.lang.model.*;
|
||||||
|
import javax.lang.model.element.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
@SupportedSourceVersion(SourceVersion.RELEASE_8)
|
||||||
|
public abstract class BaseProcessor extends AbstractProcessor{
|
||||||
|
/** Name of the base package to put all the generated classes. */
|
||||||
|
public static final String packageName = "mindustry.gen";
|
||||||
|
|
||||||
|
private int round;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void init(ProcessingEnvironment processingEnv){
|
||||||
|
super.init(processingEnv);
|
||||||
|
//put all relevant utils into utils class
|
||||||
|
Utils.typeUtils = processingEnv.getTypeUtils();
|
||||||
|
Utils.elementUtils = processingEnv.getElementUtils();
|
||||||
|
Utils.filer = processingEnv.getFiler();
|
||||||
|
Utils.messager = processingEnv.getMessager();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv){
|
||||||
|
if(round++ != 0) return false; //only process 1 round
|
||||||
|
try{
|
||||||
|
process(roundEnv);
|
||||||
|
}catch(Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void process(RoundEnvironment env) throws Exception;
|
||||||
|
}
|
||||||
@@ -14,109 +14,86 @@ import java.lang.reflect.*;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.zip.*;
|
import java.util.zip.*;
|
||||||
|
|
||||||
@SupportedSourceVersion(SourceVersion.RELEASE_8)
|
|
||||||
@SupportedAnnotationTypes("mindustry.annotations.Annotations.Serialize")
|
@SupportedAnnotationTypes("mindustry.annotations.Annotations.Serialize")
|
||||||
public class SerializeAnnotationProcessor extends AbstractProcessor{
|
public class SerializeAnnotationProcessor extends BaseProcessor{
|
||||||
/** Target class name. */
|
/** Target class name. */
|
||||||
private static final String className = "Serialization";
|
private static final String className = "Serialization";
|
||||||
/** Name of the base package to put all the generated classes. */
|
/** Name of the base package to put all the generated classes. */
|
||||||
private static final String packageName = "mindustry.gen";
|
|
||||||
private static final String data = "eJztV0tvGzcQvvfQ3zDRIeDCKhsbQVDUsgP5UViH2IHl9BIEBsUdSYxX3C3Jlawm+XH9Z53hUg/bkuOmOfRQwfDuDme++ebBWe6PfwU3/wTwUU2VLJQdSYfDAnWQvxkschjCAUyMzWtPetJikF2nzzG8deXU5OjkW6VvMPTRGVWYP0mgC+W9HGE4Qbp1mEcg0Zo5E9C1sn2AofQYulqj92ZQoAiuxqVc2Loo2iCU03JYWy2PS+v3OndJNF7bDW1rSnk0D3hUD4foDjNRtWGQwU+HQIGZoajAWB+U1VgOYROOZx+Wgm4eMzJ7ghpoyo14Cl5FsQ2I4PsPcE2/XXpssk7kOMw6mEJe9KXxXZu70uTM4Jjz2Hl9CJ79xCc5LN25mqBoqUZPVosy9DEEY0eebnTtMKZ5iaDddgRd2oA2MGO+XqIvi2mq0xJAqQ0ARHzA8dncywWar91QaZwanMkUS7eqCqNVMKW9x+qRuO6wug3R8GGLvsEwLnMYMZBS6z3XrIgWidYhLgYfyQ50IyKrkZbGTssbjHU4Lh1KVVWbvaUNEf8fUFXYX+rt7vnJ5UXv5Lp3Et30g6NagDK55RZpHrNoyUaxwx+PyA+XLtZCaYBabSpoOzlptttX0uM8oen7aJsqnhLkkixmyPlFjlLe1kL0a/ER6YVis4UXKO2YCbYyNkCBnBQv6ToKY5Gt9kauAveZxVkjYc2fYe8DT4bSCTY2tP5iny4dxuGbnQPY4+3Cxu9N1GdODJAJcTxWTmmaOzI3IxOEl5ok3SBM1obdVxl0OvAyA9iB7Zq0uNtoM9cvy9gpvLoIiXAjW+1mnwZi7Ht5pDy+enlc8k5Fq+kqmG8EpBnQIEn8o1aFp25a/C66B60sgzB25Sx6uaxtMBM8vdVYMbBoHakc3r3rnchYvjhdiBGDM1csPD4cMr3Sc8ZSGHVtuJ+X/e8Xk2TZcKLFOtR2rVYizM8EdDqpwlxkDJZKeCcnUfYLl4+f2MFEhbG8pE0uMhqXt4Gntk/hM3Ti8k0JTSgM8zCWqg7LKPiyWcurKYr1PDaYi0x+Wi08gVaOkdYT85paa+Enbubo4NTWE3QRvtO87eg1Qy/gWeluerQd47w9BCRSsHWdfd6XebGcGptMoKw58Dhe4IwrXJYFKkspEKnYfImdRB0R7+GAasezjRIXamdhSP2M+1/rjv7cB5xI5Zya67KaN2BteNFOFvE2CtPUYObJxbN/1Sxb9hw8f/7dgbsMnKoMcAbjlIezWAcecJRxkmHcGacFTmg48xrLuYBnyuUzerl185y8UPkW6YbPn+HZWFJhtmlmMSKUY+XfUC8m8NgBG52uDeXrVFnYhv3Py3u9sb7X9wu8eMUE9x1GArUoAW0rNyVw42r3WwfwanDQHx1+9FhcMYii4y6E/6fvf3T6UiaZLA3BtXO9Zvvf0Xn2MahNEfmv1unr42peYe9Cxk+chD6gU5qcNla8/GQbSwfhJyvXvslmpC2oxOXAUIe9TgegXfgVXizXOSxN4RSlW9nEnK4eGzsGolO9pw+6xXC6d/pa0yDBzs7db6ZHGEczPgSbO+88qBpVMYjSbH/Trgn0vUM8+oE+O67otMbt8uWHvwGqGwCj";
|
private static final String data = "eJztV0tvGzcQvvfQ3zDRIeDCKhsbQVDUsgP5UViH2IHl9BIEBsUdSYxX3C3Jlawm+XH9Z53hUg/bkuOmOfRQwfDuDme++ebBWe6PfwU3/wTwUU2VLJQdSYfDAnWQvxkschjCAUyMzWtPetJikF2nzzG8deXU5OjkW6VvMPTRGVWYP0mgC+W9HGE4Qbp1mEcg0Zo5E9C1sn2AofQYulqj92ZQoAiuxqVc2Loo2iCU03JYWy2PS+v3OndJNF7bDW1rSnk0D3hUD4foDjNRtWGQwU+HQIGZoajAWB+U1VgOYROOZx+Wgm4eMzJ7ghpoyo14Cl5FsQ2I4PsPcE2/XXpssk7kOMw6mEJe9KXxXZu70uTM4Jjz2Hl9CJ79xCc5LN25mqBoqUZPVosy9DEEY0eebnTtMKZ5iaDddgRd2oA2MGO+XqIvi2mq0xJAqQ0ARHzA8dncywWar91QaZwanMkUS7eqCqNVMKW9x+qRuO6wug3R8GGLvsEwLnMYMZBS6z3XrIgWidYhLgYfyQ50IyKrkZbGTssbjHU4Lh1KVVWbvaUNEf8fUFXYX+rt7vnJ5UXv5Lp3Et30g6NagDK55RZpHrNoyUaxwx+PyA+XLtZCaYBabSpoOzlptttX0uM8oen7aJsqnhLkkixmyPlFjlLe1kL0a/ER6YVis4UXKO2YCbYyNkCBnBQv6ToKY5Gt9kauAveZxVkjYc2fYe8DT4bSCTY2tP5iny4dxuGbnQPY4+3Cxu9N1GdODJAJcTxWTmmaOzI3IxOEl5ok3SBM1obdVxl0OvAyA9iB7Zq0uNtoM9cvy9gpvLoIiXAjW+1mnwZi7Ht5pDy+enlc8k5Fq+kqmG8EpBnQIEn8o1aFp25a/C66B60sgzB25Sx6uaxtMBM8vdVYMbBoHakc3r3rnchYvjhdiBGDM1csPD4cMr3Sc8ZSGHVtuJ+X/e8Xk2TZcKLFOtR2rVYizM8EdDqpwlxkDJZKeCcnUfYLl4+f2MFEhbG8pE0uMhqXt4Gntk/hM3Ti8k0JTSgM8zCWqg7LKPiyWcurKYr1PDaYi0x+Wi08gVaOkdYT85paa+Enbubo4NTWE3QRvtO87eg1Qy/gWeluerQd47w9BCRSsHWdfd6XebGcGptMoKw58Dhe4IwrXJYFKkspEKnYfImdRB0R7+GAasezjRIXamdhSP2M+1/rjv7cB5xI5Zya67KaN2BteNFOFvE2CtPUYObJxbN/1Sxb9hw8f/7dgbsMnKoMcAbjlIezWAcecJRxkmHcGacFTmg48xrLuYBnyuUzerl185y8UPkW6YbPn+HZWFJhtmlmMSKUY+XfUC8m8NgBG52uDeXrVFnYhv3Py3u9sb7X9wu8eMUE9x1GArUoAW0rNyVw42r3WwfwanDQHx1+9FhcMYii4y6E/6fvf3T6UiaZLA3BtXO9Zvvf0Xn2MahNEfmv1unr42peYe9Cxk+chD6gU5qcNla8/GQbSwfhJyvXvslmpC2oxOXAUIe9TgegXfgVXizXOSxN4RSlW9nEnK4eGzsGolO9pw+6xXC6d/pa0yDBzs7db6ZHGEczPgSbO+88qBpVMYjSbH/Trgn0vUM8+oE+O67otMbt8uWHvwGqGwCj";
|
||||||
|
|
||||||
private int round;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv){
|
public void process(RoundEnvironment env) throws Exception{
|
||||||
if(round++ != 0) return false; //only process 1 round
|
Set<TypeElement> elements = ElementFilter.typesIn(env.getElementsAnnotatedWith(Serialize.class));
|
||||||
|
|
||||||
try{
|
TypeSpec.Builder classBuilder = TypeSpec.classBuilder(className).addModifiers(Modifier.PUBLIC);
|
||||||
Set<TypeElement> elements = ElementFilter.typesIn(roundEnv.getElementsAnnotatedWith(Serialize.class));
|
classBuilder.addStaticBlock(CodeBlock.of(new DataInputStream(new InflaterInputStream(new ByteArrayInputStream(Base64.getDecoder().decode(data)))).readUTF()));
|
||||||
|
classBuilder.addAnnotation(AnnotationSpec.builder(SuppressWarnings.class).addMember("value", "\"unchecked\"").build());
|
||||||
|
classBuilder.addJavadoc(RemoteMethodAnnotationProcessor.autogenWarning);
|
||||||
|
|
||||||
TypeSpec.Builder classBuilder = TypeSpec.classBuilder(className).addModifiers(Modifier.PUBLIC);
|
MethodSpec.Builder method = MethodSpec.methodBuilder("init").addModifiers(Modifier.PUBLIC, Modifier.STATIC);
|
||||||
classBuilder.addStaticBlock(CodeBlock.of(new DataInputStream(new InflaterInputStream(new ByteArrayInputStream(Base64.getDecoder().decode(data)))).readUTF()));
|
|
||||||
classBuilder.addAnnotation(AnnotationSpec.builder(SuppressWarnings.class).addMember("value", "\"unchecked\"").build());
|
|
||||||
classBuilder.addJavadoc(RemoteMethodAnnotationProcessor.autogenWarning);
|
|
||||||
|
|
||||||
MethodSpec.Builder method = MethodSpec.methodBuilder("init").addModifiers(Modifier.PUBLIC, Modifier.STATIC);
|
for(TypeElement elem : elements){
|
||||||
|
TypeName type = TypeName.get(elem.asType());
|
||||||
|
String simpleTypeName = type.toString().substring(type.toString().lastIndexOf('.') + 1);
|
||||||
|
|
||||||
for(TypeElement elem : elements){
|
TypeSpec.Builder serializer = TypeSpec.anonymousClassBuilder("")
|
||||||
TypeName type = TypeName.get(elem.asType());
|
.addSuperinterface(ParameterizedTypeName.get(
|
||||||
String simpleTypeName = type.toString().substring(type.toString().lastIndexOf('.') + 1);
|
ClassName.bestGuess("arc.Settings.TypeSerializer"), type));
|
||||||
|
|
||||||
TypeSpec.Builder serializer = TypeSpec.anonymousClassBuilder("")
|
MethodSpec.Builder writeMethod = MethodSpec.methodBuilder("write")
|
||||||
.addSuperinterface(ParameterizedTypeName.get(
|
.returns(void.class)
|
||||||
ClassName.bestGuess("arc.Settings.TypeSerializer"), type));
|
.addParameter(DataOutput.class, "stream")
|
||||||
|
.addParameter(type, "object")
|
||||||
|
.addException(IOException.class)
|
||||||
|
.addModifiers(Modifier.PUBLIC);
|
||||||
|
|
||||||
MethodSpec.Builder writeMethod = MethodSpec.methodBuilder("write")
|
MethodSpec.Builder readMethod = MethodSpec.methodBuilder("read")
|
||||||
.returns(void.class)
|
.returns(type)
|
||||||
.addParameter(DataOutput.class, "stream")
|
.addParameter(DataInput.class, "stream")
|
||||||
.addParameter(type, "object")
|
.addException(IOException.class)
|
||||||
.addException(IOException.class)
|
.addModifiers(Modifier.PUBLIC);
|
||||||
.addModifiers(Modifier.PUBLIC);
|
|
||||||
|
|
||||||
MethodSpec.Builder readMethod = MethodSpec.methodBuilder("read")
|
readMethod.addStatement("$L object = new $L()", type, type);
|
||||||
.returns(type)
|
|
||||||
.addParameter(DataInput.class, "stream")
|
|
||||||
.addException(IOException.class)
|
|
||||||
.addModifiers(Modifier.PUBLIC);
|
|
||||||
|
|
||||||
readMethod.addStatement("$L object = new $L()", type, type);
|
List<VariableElement> fields = ElementFilter.fieldsIn(Utils.elementUtils.getAllMembers(elem));
|
||||||
|
for(VariableElement field : fields){
|
||||||
|
if(field.getModifiers().contains(Modifier.STATIC) || field.getModifiers().contains(Modifier.TRANSIENT) || field.getModifiers().contains(Modifier.PRIVATE))
|
||||||
|
continue;
|
||||||
|
|
||||||
List<VariableElement> fields = ElementFilter.fieldsIn(Utils.elementUtils.getAllMembers(elem));
|
String name = field.getSimpleName().toString();
|
||||||
for(VariableElement field : fields){
|
String typeName = Utils.typeUtils.erasure(field.asType()).toString().replace('$', '.');
|
||||||
if(field.getModifiers().contains(Modifier.STATIC) || field.getModifiers().contains(Modifier.TRANSIENT) || field.getModifiers().contains(Modifier.PRIVATE))
|
String capName = Character.toUpperCase(typeName.charAt(0)) + typeName.substring(1);
|
||||||
continue;
|
|
||||||
|
|
||||||
String name = field.getSimpleName().toString();
|
if(field.asType().getKind().isPrimitive()){
|
||||||
String typeName = Utils.typeUtils.erasure(field.asType()).toString().replace('$', '.');
|
writeMethod.addStatement("stream.write" + capName + "(object." + name + ")");
|
||||||
String capName = Character.toUpperCase(typeName.charAt(0)) + typeName.substring(1);
|
readMethod.addStatement("object." + name + "= stream.read" + capName + "()");
|
||||||
|
}else{
|
||||||
if(field.asType().getKind().isPrimitive()){
|
writeMethod.addStatement("arc.Core.settings.getSerializer(" + typeName + ".class).write(stream, object." + name + ")");
|
||||||
writeMethod.addStatement("stream.write" + capName + "(object." + name + ")");
|
readMethod.addStatement("object." + name + " = (" + typeName + ")arc.Core.settings.getSerializer(" + typeName + ".class).read(stream)");
|
||||||
readMethod.addStatement("object." + name + "= stream.read" + capName + "()");
|
|
||||||
}else{
|
|
||||||
writeMethod.addStatement("arc.Core.settings.getSerializer(" + typeName + ".class).write(stream, object." + name + ")");
|
|
||||||
readMethod.addStatement("object." + name + " = (" + typeName + ")arc.Core.settings.getSerializer(" + typeName + ".class).read(stream)");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
readMethod.addStatement("return object");
|
|
||||||
|
|
||||||
serializer.addMethod(writeMethod.build());
|
|
||||||
serializer.addMethod(readMethod.build());
|
|
||||||
|
|
||||||
method.addStatement("arc.Core.settings.setSerializer($N, $L)", Utils.elementUtils.getBinaryName(elem).toString().replace('$', '.') + ".class", serializer.build());
|
|
||||||
|
|
||||||
name(writeMethod, "write" + simpleTypeName);
|
|
||||||
name(readMethod, "read" + simpleTypeName);
|
|
||||||
|
|
||||||
writeMethod.addModifiers(Modifier.STATIC);
|
|
||||||
readMethod.addModifiers(Modifier.STATIC);
|
|
||||||
|
|
||||||
classBuilder.addMethod(writeMethod.build());
|
|
||||||
classBuilder.addMethod(readMethod.build());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
classBuilder.addMethod(method.build());
|
readMethod.addStatement("return object");
|
||||||
|
|
||||||
//write result
|
serializer.addMethod(writeMethod.build());
|
||||||
JavaFile.builder(packageName, classBuilder.build()).build().writeTo(Utils.filer);
|
serializer.addMethod(readMethod.build());
|
||||||
|
|
||||||
return true;
|
method.addStatement("arc.Core.settings.setSerializer($N, $L)", Utils.elementUtils.getBinaryName(elem).toString().replace('$', '.') + ".class", serializer.build());
|
||||||
}catch(Exception e){
|
|
||||||
e.printStackTrace();
|
name(writeMethod, "write" + simpleTypeName);
|
||||||
throw new RuntimeException(e);
|
name(readMethod, "read" + simpleTypeName);
|
||||||
|
|
||||||
|
writeMethod.addModifiers(Modifier.STATIC);
|
||||||
|
readMethod.addModifiers(Modifier.STATIC);
|
||||||
|
|
||||||
|
classBuilder.addMethod(writeMethod.build());
|
||||||
|
classBuilder.addMethod(readMethod.build());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
classBuilder.addMethod(method.build());
|
||||||
public synchronized void init(ProcessingEnvironment processingEnv){
|
|
||||||
super.init(processingEnv);
|
//write result
|
||||||
//put all relevant utils into utils class
|
JavaFile.builder(packageName, classBuilder.build()).build().writeTo(Utils.filer);
|
||||||
Utils.typeUtils = processingEnv.getTypeUtils();
|
|
||||||
Utils.elementUtils = processingEnv.getElementUtils();
|
|
||||||
Utils.filer = processingEnv.getFiler();
|
|
||||||
Utils.messager = processingEnv.getMessager();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void name(MethodSpec.Builder builder, String name){
|
static void name(MethodSpec.Builder builder, String name){
|
||||||
|
|||||||
@@ -17,148 +17,126 @@ 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.
|
||||||
* It would be nice if Java didn't make crazy hacks like this necessary.
|
* It would be nice if Java didn't make crazy hacks like this necessary.
|
||||||
*/
|
*/
|
||||||
@SupportedSourceVersion(SourceVersion.RELEASE_8)
|
|
||||||
@SupportedAnnotationTypes({
|
@SupportedAnnotationTypes({
|
||||||
"mindustry.annotations.Annotations.Struct"
|
"mindustry.annotations.Annotations.Struct"
|
||||||
})
|
})
|
||||||
public class StructAnnotationProcessor extends AbstractProcessor{
|
public class StructAnnotationProcessor extends BaseProcessor{
|
||||||
/** Name of the base package to put all the generated classes. */
|
|
||||||
private static final String packageName = "mindustry.gen";
|
|
||||||
private int round;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void init(ProcessingEnvironment processingEnv){
|
public void process(RoundEnvironment env) throws Exception{
|
||||||
super.init(processingEnv);
|
Set<TypeElement> elements = ElementFilter.typesIn(env.getElementsAnnotatedWith(Struct.class));
|
||||||
//put all relevant utils into utils class
|
|
||||||
Utils.typeUtils = processingEnv.getTypeUtils();
|
|
||||||
Utils.elementUtils = processingEnv.getElementUtils();
|
|
||||||
Utils.filer = processingEnv.getFiler();
|
|
||||||
Utils.messager = processingEnv.getMessager();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
for(TypeElement elem : elements){
|
||||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv){
|
|
||||||
if(round++ != 0) return false; //only process 1 round
|
|
||||||
|
|
||||||
try{
|
if(!elem.getSimpleName().toString().endsWith("Struct")){
|
||||||
Set<TypeElement> elements = ElementFilter.typesIn(roundEnv.getElementsAnnotatedWith(Struct.class));
|
Utils.messager.printMessage(Kind.ERROR, "All classes annotated with @Struct must have their class names end in 'Struct'.", elem);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for(TypeElement elem : elements){
|
String structName = elem.getSimpleName().toString().substring(0, elem.getSimpleName().toString().length() - "Struct".length());
|
||||||
|
String structParam = structName.toLowerCase();
|
||||||
|
|
||||||
if(!elem.getSimpleName().toString().endsWith("Struct")){
|
TypeSpec.Builder classBuilder = TypeSpec.classBuilder(structName)
|
||||||
Utils.messager.printMessage(Kind.ERROR, "All classes annotated with @Struct must have their class names end in 'Struct'.", elem);
|
.addModifiers(Modifier.FINAL, Modifier.PUBLIC);
|
||||||
|
|
||||||
|
try{
|
||||||
|
List<VariableElement> variables = ElementFilter.fieldsIn(elem.getEnclosedElements());
|
||||||
|
int structSize = variables.stream().mapToInt(StructAnnotationProcessor::varSize).sum();
|
||||||
|
int structTotalSize = (structSize <= 8 ? 8 : structSize <= 16 ? 16 : structSize <= 32 ? 32 : 64);
|
||||||
|
|
||||||
|
if(variables.size() == 0){
|
||||||
|
Utils.messager.printMessage(Kind.ERROR, "making a struct with no fields is utterly pointles.", elem);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
String structName = elem.getSimpleName().toString().substring(0, elem.getSimpleName().toString().length() - "Struct".length());
|
//obtain type which will be stored
|
||||||
String structParam = structName.toLowerCase();
|
Class<?> structType = typeForSize(structSize);
|
||||||
|
|
||||||
TypeSpec.Builder classBuilder = TypeSpec.classBuilder(structName)
|
//[constructor] get(fields...) : structType
|
||||||
.addModifiers(Modifier.FINAL, Modifier.PUBLIC);
|
MethodSpec.Builder constructor = MethodSpec.methodBuilder("get")
|
||||||
|
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
|
||||||
|
.returns(structType);
|
||||||
|
|
||||||
try{
|
StringBuilder cons = new StringBuilder();
|
||||||
List<VariableElement> variables = ElementFilter.fieldsIn(elem.getEnclosedElements());
|
StringBuilder doc = new StringBuilder();
|
||||||
int structSize = variables.stream().mapToInt(StructAnnotationProcessor::varSize).sum();
|
doc.append("Bits used: ").append(structSize).append(" / ").append(structTotalSize).append("\n");
|
||||||
int structTotalSize = (structSize <= 8 ? 8 : structSize <= 16 ? 16 : structSize <= 32 ? 32 : 64);
|
|
||||||
|
|
||||||
if(variables.size() == 0){
|
int offset = 0;
|
||||||
Utils.messager.printMessage(Kind.ERROR, "making a struct with no fields is utterly pointles.", elem);
|
for(VariableElement var : variables){
|
||||||
continue;
|
int size = varSize(var);
|
||||||
}
|
TypeName varType = TypeName.get(var.asType());
|
||||||
|
String varName = var.getSimpleName().toString();
|
||||||
|
|
||||||
//obtain type which will be stored
|
//add val param to constructor
|
||||||
Class<?> structType = typeForSize(structSize);
|
constructor.addParameter(varType, varName);
|
||||||
|
|
||||||
//[constructor] get(fields...) : structType
|
//[get] field(structType) : fieldType
|
||||||
MethodSpec.Builder constructor = MethodSpec.methodBuilder("get")
|
MethodSpec.Builder getter = MethodSpec.methodBuilder(var.getSimpleName().toString())
|
||||||
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
|
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
|
||||||
.returns(structType);
|
.returns(varType)
|
||||||
|
.addParameter(structType, structParam);
|
||||||
|
//[set] field(structType, fieldType) : structType
|
||||||
|
MethodSpec.Builder setter = MethodSpec.methodBuilder(var.getSimpleName().toString())
|
||||||
|
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
|
||||||
|
.returns(structType)
|
||||||
|
.addParameter(structType, structParam).addParameter(varType, "value");
|
||||||
|
|
||||||
StringBuilder cons = new StringBuilder();
|
//[getter]
|
||||||
StringBuilder doc = new StringBuilder();
|
if(varType == TypeName.BOOLEAN){
|
||||||
doc.append("Bits used: ").append(structSize).append(" / ").append(structTotalSize).append("\n");
|
//bools: single bit, is simplified
|
||||||
|
getter.addStatement("return ($L & (1L << $L)) != 0", structParam, offset);
|
||||||
int offset = 0;
|
}else if(varType == TypeName.FLOAT){
|
||||||
for(VariableElement var : variables){
|
//floats: need conversion
|
||||||
int size = varSize(var);
|
getter.addStatement("return Float.intBitsToFloat((int)(($L >>> $L) & $L))", structParam, offset, bitString(size, structTotalSize));
|
||||||
TypeName varType = TypeName.get(var.asType());
|
}else{
|
||||||
String varName = var.getSimpleName().toString();
|
//bytes, shorts, chars, ints
|
||||||
|
getter.addStatement("return ($T)(($L >>> $L) & $L)", varType, structParam, offset, bitString(size, structTotalSize));
|
||||||
//add val param to constructor
|
|
||||||
constructor.addParameter(varType, varName);
|
|
||||||
|
|
||||||
//[get] field(structType) : fieldType
|
|
||||||
MethodSpec.Builder getter = MethodSpec.methodBuilder(var.getSimpleName().toString())
|
|
||||||
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
|
|
||||||
.returns(varType)
|
|
||||||
.addParameter(structType, structParam);
|
|
||||||
//[set] field(structType, fieldType) : structType
|
|
||||||
MethodSpec.Builder setter = MethodSpec.methodBuilder(var.getSimpleName().toString())
|
|
||||||
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
|
|
||||||
.returns(structType)
|
|
||||||
.addParameter(structType, structParam).addParameter(varType, "value");
|
|
||||||
|
|
||||||
//[getter]
|
|
||||||
if(varType == TypeName.BOOLEAN){
|
|
||||||
//bools: single bit, is simplified
|
|
||||||
getter.addStatement("return ($L & (1L << $L)) != 0", structParam, offset);
|
|
||||||
}else if(varType == TypeName.FLOAT){
|
|
||||||
//floats: need conversion
|
|
||||||
getter.addStatement("return Float.intBitsToFloat((int)(($L >>> $L) & $L))", structParam, offset, bitString(size, structTotalSize));
|
|
||||||
}else{
|
|
||||||
//bytes, shorts, chars, ints
|
|
||||||
getter.addStatement("return ($T)(($L >>> $L) & $L)", varType, structParam, offset, bitString(size, structTotalSize));
|
|
||||||
}
|
|
||||||
|
|
||||||
//[setter] + [constructor building]
|
|
||||||
if(varType == TypeName.BOOLEAN){
|
|
||||||
cons.append(" | (").append(varName).append(" ? ").append("1L << ").append(offset).append("L : 0)");
|
|
||||||
|
|
||||||
//bools: single bit, needs special case to clear things
|
|
||||||
setter.beginControlFlow("if(value)");
|
|
||||||
setter.addStatement("return ($T)(($L & ~(1L << $LL)))", structType, structParam, offset);
|
|
||||||
setter.nextControlFlow("else");
|
|
||||||
setter.addStatement("return ($T)(($L & ~(1L << $LL)) | (1L << $LL))", structType, structParam, offset, offset);
|
|
||||||
setter.endControlFlow();
|
|
||||||
}else if(varType == TypeName.FLOAT){
|
|
||||||
cons.append(" | (").append("(").append(structType).append(")").append("Float.floatToIntBits(").append(varName).append(") << ").append(offset).append("L)");
|
|
||||||
|
|
||||||
//floats: need conversion
|
|
||||||
setter.addStatement("return ($T)(($L & $L) | (($T)Float.floatToIntBits(value) << $LL))", structType, structParam, bitString(offset, size, structTotalSize), structType, offset);
|
|
||||||
}else{
|
|
||||||
cons.append(" | (((").append(structType).append(")").append(varName).append(" << ").append(offset).append("L)").append(" & ").append(bitString(offset, size, structTotalSize)).append(")");
|
|
||||||
|
|
||||||
//bytes, shorts, chars, ints
|
|
||||||
setter.addStatement("return ($T)(($L & $L) | (($T)value << $LL))", structType, structParam, bitString(offset, size, structTotalSize), structType, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
doc.append("<br> ").append(varName).append(" [").append(offset).append("..").append(size + offset).append("]\n");
|
|
||||||
|
|
||||||
//add finished methods
|
|
||||||
classBuilder.addMethod(getter.build());
|
|
||||||
classBuilder.addMethod(setter.build());
|
|
||||||
|
|
||||||
offset += size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
classBuilder.addJavadoc(doc.toString());
|
//[setter] + [constructor building]
|
||||||
|
if(varType == TypeName.BOOLEAN){
|
||||||
|
cons.append(" | (").append(varName).append(" ? ").append("1L << ").append(offset).append("L : 0)");
|
||||||
|
|
||||||
//add constructor final statement + add to class and build
|
//bools: single bit, needs special case to clear things
|
||||||
constructor.addStatement("return ($T)($L)", structType, cons.toString().substring(3));
|
setter.beginControlFlow("if(value)");
|
||||||
classBuilder.addMethod(constructor.build());
|
setter.addStatement("return ($T)(($L & ~(1L << $LL)))", structType, structParam, offset);
|
||||||
|
setter.nextControlFlow("else");
|
||||||
|
setter.addStatement("return ($T)(($L & ~(1L << $LL)) | (1L << $LL))", structType, structParam, offset, offset);
|
||||||
|
setter.endControlFlow();
|
||||||
|
}else if(varType == TypeName.FLOAT){
|
||||||
|
cons.append(" | (").append("(").append(structType).append(")").append("Float.floatToIntBits(").append(varName).append(") << ").append(offset).append("L)");
|
||||||
|
|
||||||
JavaFile.builder(packageName, classBuilder.build()).build().writeTo(Utils.filer);
|
//floats: need conversion
|
||||||
}catch(IllegalArgumentException e){
|
setter.addStatement("return ($T)(($L & $L) | (($T)Float.floatToIntBits(value) << $LL))", structType, structParam, bitString(offset, size, structTotalSize), structType, offset);
|
||||||
e.printStackTrace();
|
}else{
|
||||||
Utils.messager.printMessage(Kind.ERROR, e.getMessage(), elem);
|
cons.append(" | (((").append(structType).append(")").append(varName).append(" << ").append(offset).append("L)").append(" & ").append(bitString(offset, size, structTotalSize)).append(")");
|
||||||
|
|
||||||
|
//bytes, shorts, chars, ints
|
||||||
|
setter.addStatement("return ($T)(($L & $L) | (($T)value << $LL))", structType, structParam, bitString(offset, size, structTotalSize), structType, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
doc.append("<br> ").append(varName).append(" [").append(offset).append("..").append(size + offset).append("]\n");
|
||||||
|
|
||||||
|
//add finished methods
|
||||||
|
classBuilder.addMethod(getter.build());
|
||||||
|
classBuilder.addMethod(setter.build());
|
||||||
|
|
||||||
|
offset += size;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
classBuilder.addJavadoc(doc.toString());
|
||||||
}catch(Exception e){
|
|
||||||
e.printStackTrace();
|
//add constructor final statement + add to class and build
|
||||||
throw new RuntimeException(e);
|
constructor.addStatement("return ($T)($L)", structType, cons.toString().substring(3));
|
||||||
|
classBuilder.addMethod(constructor.build());
|
||||||
|
|
||||||
|
JavaFile.builder(packageName, classBuilder.build()).build().writeTo(Utils.filer);
|
||||||
|
}catch(IllegalArgumentException e){
|
||||||
|
e.printStackTrace();
|
||||||
|
Utils.messager.printMessage(Kind.ERROR, e.getMessage(), elem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static String bitString(int offset, int size, int totalSize){
|
static String bitString(int offset, int size, int totalSize){
|
||||||
|
|||||||
+3
-1
@@ -308,8 +308,10 @@ project(":annotations"){
|
|||||||
apply plugin: "java"
|
apply plugin: "java"
|
||||||
|
|
||||||
dependencies{
|
dependencies{
|
||||||
|
def arcVersion = "e287fdce0449a87fb15599c67b5167ac0273bcb6"
|
||||||
|
|
||||||
compile 'com.squareup:javapoet:1.11.0'
|
compile 'com.squareup:javapoet:1.11.0'
|
||||||
compile "com.github.Anuken.Arc:arc-core:b77767039334b2658f44d69e72d1ef6bc84f95b0"
|
compile "com.github.Anuken.Arc:arc-core:$arcVersion"
|
||||||
compile files("${System.getProperty('java.home')}/../lib/tools.jar")
|
compile files("${System.getProperty('java.home')}/../lib/tools.jar")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ import java.util.*;
|
|||||||
|
|
||||||
import static arc.Core.settings;
|
import static arc.Core.settings;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public class Vars implements Loadable{
|
public class Vars implements Loadable{
|
||||||
/** Whether to load locales.*/
|
/** Whether to load locales.*/
|
||||||
public static boolean loadLocales = true;
|
public static boolean loadLocales = true;
|
||||||
@@ -60,7 +59,7 @@ public class Vars implements Loadable{
|
|||||||
public static final String serverJsonURL = "https://raw.githubusercontent.com/Anuken/Mindustry/master/servers.json";
|
public static final String serverJsonURL = "https://raw.githubusercontent.com/Anuken/Mindustry/master/servers.json";
|
||||||
/** URL to the JSON file containing all the BE servers. Only queried in BE. */
|
/** URL to the JSON file containing all the BE servers. Only queried in BE. */
|
||||||
public static final String serverJsonBeURL = "https://raw.githubusercontent.com/Anuken/Mindustry/master/servers_be.json";
|
public static final String serverJsonBeURL = "https://raw.githubusercontent.com/Anuken/Mindustry/master/servers_be.json";
|
||||||
/** URL the links to the wiki's modding guide.*/
|
/** URL of the github issue report template.*/
|
||||||
public static final String reportIssueURL = "https://github.com/Anuken/Mindustry/issues/new?template=bug_report.md";
|
public static final String reportIssueURL = "https://github.com/Anuken/Mindustry/issues/new?template=bug_report.md";
|
||||||
/** list of built-in servers.*/
|
/** list of built-in servers.*/
|
||||||
public static final Array<String> defaultServers = Array.with();
|
public static final Array<String> defaultServers = Array.with();
|
||||||
|
|||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
org.gradle.daemon=true
|
org.gradle.daemon=true
|
||||||
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
||||||
archash=bf5f253d458e0b8bddf9efcc3642a644f4b48fb6
|
archash=e287fdce0449a87fb15599c67b5167ac0273bcb6
|
||||||
|
|||||||
Reference in New Issue
Block a user