From 5e977312a7b302b860d604165246a66d391ee374 Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 22 Jan 2020 12:24:00 -0500 Subject: [PATCH] Annotation processor cleanup --- .../AssetsAnnotationProcessor.java | 41 +--- .../mindustry/annotations/BaseProcessor.java | 38 ++++ .../SerializeAnnotationProcessor.java | 135 +++++------ .../StructAnnotationProcessor.java | 210 ++++++++---------- build.gradle | 4 +- core/src/mindustry/Vars.java | 3 +- gradle.properties | 2 +- 7 files changed, 202 insertions(+), 231 deletions(-) create mode 100644 annotations/src/main/java/mindustry/annotations/BaseProcessor.java diff --git a/annotations/src/main/java/mindustry/annotations/AssetsAnnotationProcessor.java b/annotations/src/main/java/mindustry/annotations/AssetsAnnotationProcessor.java index 89bd5bde27..0ef33f671d 100644 --- a/annotations/src/main/java/mindustry/annotations/AssetsAnnotationProcessor.java +++ b/annotations/src/main/java/mindustry/annotations/AssetsAnnotationProcessor.java @@ -14,43 +14,20 @@ import javax.tools.Diagnostic.*; import javax.tools.*; import java.util.*; -@SupportedSourceVersion(SourceVersion.RELEASE_8) @SupportedAnnotationTypes("mindustry.annotations.Annotations.StyleDefaults") -public class AssetsAnnotationProcessor extends AbstractProcessor{ - /** Name of the base package to put all the generated classes. */ - private static final String packageName = "mindustry.gen"; +public class AssetsAnnotationProcessor extends BaseProcessor{ private String path; - 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(); - } + public void process(RoundEnvironment env) throws Exception{ + 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", " "); - @Override - public boolean process(Set annotations, RoundEnvironment roundEnv){ - if(round++ != 0) return false; //only process 1 round - - 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); - } + processSounds("Sounds", path + "/assets/sounds", "arc.audio.Sound"); + processSounds("Musics", path + "/assets/music", "arc.audio.Music"); + processUI(env.getElementsAnnotatedWith(StyleDefaults.class)); } void processUI(Set elements) throws Exception{ diff --git a/annotations/src/main/java/mindustry/annotations/BaseProcessor.java b/annotations/src/main/java/mindustry/annotations/BaseProcessor.java new file mode 100644 index 0000000000..b533f26c56 --- /dev/null +++ b/annotations/src/main/java/mindustry/annotations/BaseProcessor.java @@ -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 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; +} diff --git a/annotations/src/main/java/mindustry/annotations/SerializeAnnotationProcessor.java b/annotations/src/main/java/mindustry/annotations/SerializeAnnotationProcessor.java index 117c421176..16ebcc9ead 100644 --- a/annotations/src/main/java/mindustry/annotations/SerializeAnnotationProcessor.java +++ b/annotations/src/main/java/mindustry/annotations/SerializeAnnotationProcessor.java @@ -14,109 +14,86 @@ import java.lang.reflect.*; import java.util.*; import java.util.zip.*; -@SupportedSourceVersion(SourceVersion.RELEASE_8) @SupportedAnnotationTypes("mindustry.annotations.Annotations.Serialize") -public class SerializeAnnotationProcessor extends AbstractProcessor{ +public class SerializeAnnotationProcessor extends BaseProcessor{ /** Target class name. */ private static final String className = "Serialization"; /** 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 int round; - @Override - public boolean process(Set annotations, RoundEnvironment roundEnv){ - if(round++ != 0) return false; //only process 1 round + public void process(RoundEnvironment env) throws Exception{ + Set elements = ElementFilter.typesIn(env.getElementsAnnotatedWith(Serialize.class)); - try{ - Set elements = ElementFilter.typesIn(roundEnv.getElementsAnnotatedWith(Serialize.class)); + TypeSpec.Builder classBuilder = TypeSpec.classBuilder(className).addModifiers(Modifier.PUBLIC); + 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); - 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); - 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){ - TypeName type = TypeName.get(elem.asType()); - String simpleTypeName = type.toString().substring(type.toString().lastIndexOf('.') + 1); + TypeSpec.Builder serializer = TypeSpec.anonymousClassBuilder("") + .addSuperinterface(ParameterizedTypeName.get( + ClassName.bestGuess("arc.Settings.TypeSerializer"), type)); - TypeSpec.Builder serializer = TypeSpec.anonymousClassBuilder("") - .addSuperinterface(ParameterizedTypeName.get( - ClassName.bestGuess("arc.Settings.TypeSerializer"), type)); + MethodSpec.Builder writeMethod = MethodSpec.methodBuilder("write") + .returns(void.class) + .addParameter(DataOutput.class, "stream") + .addParameter(type, "object") + .addException(IOException.class) + .addModifiers(Modifier.PUBLIC); - MethodSpec.Builder writeMethod = MethodSpec.methodBuilder("write") - .returns(void.class) - .addParameter(DataOutput.class, "stream") - .addParameter(type, "object") - .addException(IOException.class) - .addModifiers(Modifier.PUBLIC); + MethodSpec.Builder readMethod = MethodSpec.methodBuilder("read") + .returns(type) + .addParameter(DataInput.class, "stream") + .addException(IOException.class) + .addModifiers(Modifier.PUBLIC); - MethodSpec.Builder readMethod = MethodSpec.methodBuilder("read") - .returns(type) - .addParameter(DataInput.class, "stream") - .addException(IOException.class) - .addModifiers(Modifier.PUBLIC); + readMethod.addStatement("$L object = new $L()", type, type); - readMethod.addStatement("$L object = new $L()", type, type); + List 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 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; + String name = field.getSimpleName().toString(); + String typeName = Utils.typeUtils.erasure(field.asType()).toString().replace('$', '.'); + String capName = Character.toUpperCase(typeName.charAt(0)) + typeName.substring(1); - String name = field.getSimpleName().toString(); - String typeName = Utils.typeUtils.erasure(field.asType()).toString().replace('$', '.'); - String capName = Character.toUpperCase(typeName.charAt(0)) + typeName.substring(1); - - if(field.asType().getKind().isPrimitive()){ - writeMethod.addStatement("stream.write" + capName + "(object." + name + ")"); - 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)"); - } + if(field.asType().getKind().isPrimitive()){ + writeMethod.addStatement("stream.write" + capName + "(object." + name + ")"); + 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 - JavaFile.builder(packageName, classBuilder.build()).build().writeTo(Utils.filer); + serializer.addMethod(writeMethod.build()); + serializer.addMethod(readMethod.build()); - return true; - }catch(Exception e){ - e.printStackTrace(); - throw new RuntimeException(e); + 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()); } - } - @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(); + classBuilder.addMethod(method.build()); + + //write result + JavaFile.builder(packageName, classBuilder.build()).build().writeTo(Utils.filer); } static void name(MethodSpec.Builder builder, String name){ diff --git a/annotations/src/main/java/mindustry/annotations/StructAnnotationProcessor.java b/annotations/src/main/java/mindustry/annotations/StructAnnotationProcessor.java index 632e14a91a..48d5cf33f0 100644 --- a/annotations/src/main/java/mindustry/annotations/StructAnnotationProcessor.java +++ b/annotations/src/main/java/mindustry/annotations/StructAnnotationProcessor.java @@ -17,148 +17,126 @@ import java.util.Set; * 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. */ -@SupportedSourceVersion(SourceVersion.RELEASE_8) @SupportedAnnotationTypes({ "mindustry.annotations.Annotations.Struct" }) -public class StructAnnotationProcessor extends AbstractProcessor{ - /** Name of the base package to put all the generated classes. */ - private static final String packageName = "mindustry.gen"; - private int round; +public class StructAnnotationProcessor extends BaseProcessor{ @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(); - } + public void process(RoundEnvironment env) throws Exception{ + Set elements = ElementFilter.typesIn(env.getElementsAnnotatedWith(Struct.class)); - @Override - public boolean process(Set annotations, RoundEnvironment roundEnv){ - if(round++ != 0) return false; //only process 1 round + for(TypeElement elem : elements){ - try{ - Set elements = ElementFilter.typesIn(roundEnv.getElementsAnnotatedWith(Struct.class)); + if(!elem.getSimpleName().toString().endsWith("Struct")){ + 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")){ - Utils.messager.printMessage(Kind.ERROR, "All classes annotated with @Struct must have their class names end in 'Struct'.", elem); + TypeSpec.Builder classBuilder = TypeSpec.classBuilder(structName) + .addModifiers(Modifier.FINAL, Modifier.PUBLIC); + + try{ + List 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; } - String structName = elem.getSimpleName().toString().substring(0, elem.getSimpleName().toString().length() - "Struct".length()); - String structParam = structName.toLowerCase(); + //obtain type which will be stored + Class structType = typeForSize(structSize); - TypeSpec.Builder classBuilder = TypeSpec.classBuilder(structName) - .addModifiers(Modifier.FINAL, Modifier.PUBLIC); + //[constructor] get(fields...) : structType + MethodSpec.Builder constructor = MethodSpec.methodBuilder("get") + .addModifiers(Modifier.STATIC, Modifier.PUBLIC) + .returns(structType); - try{ - List 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); + StringBuilder cons = new StringBuilder(); + StringBuilder doc = new StringBuilder(); + doc.append("Bits used: ").append(structSize).append(" / ").append(structTotalSize).append("\n"); - if(variables.size() == 0){ - Utils.messager.printMessage(Kind.ERROR, "making a struct with no fields is utterly pointles.", elem); - continue; - } + int offset = 0; + for(VariableElement var : variables){ + int size = varSize(var); + TypeName varType = TypeName.get(var.asType()); + String varName = var.getSimpleName().toString(); - //obtain type which will be stored - Class structType = typeForSize(structSize); + //add val param to constructor + constructor.addParameter(varType, varName); - //[constructor] get(fields...) : structType - MethodSpec.Builder constructor = MethodSpec.methodBuilder("get") + //[get] field(structType) : fieldType + MethodSpec.Builder getter = MethodSpec.methodBuilder(var.getSimpleName().toString()) .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(); - StringBuilder doc = new StringBuilder(); - doc.append("Bits used: ").append(structSize).append(" / ").append(structTotalSize).append("\n"); - - int offset = 0; - for(VariableElement var : variables){ - int size = varSize(var); - TypeName varType = TypeName.get(var.asType()); - String varName = var.getSimpleName().toString(); - - //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("
").append(varName).append(" [").append(offset).append("..").append(size + offset).append("]\n"); - - //add finished methods - classBuilder.addMethod(getter.build()); - classBuilder.addMethod(setter.build()); - - offset += size; + //[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)); } - 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 - constructor.addStatement("return ($T)($L)", structType, cons.toString().substring(3)); - classBuilder.addMethod(constructor.build()); + //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)"); - JavaFile.builder(packageName, classBuilder.build()).build().writeTo(Utils.filer); - }catch(IllegalArgumentException e){ - e.printStackTrace(); - Utils.messager.printMessage(Kind.ERROR, e.getMessage(), elem); + //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("
").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; - }catch(Exception e){ - e.printStackTrace(); - throw new RuntimeException(e); + classBuilder.addJavadoc(doc.toString()); + + //add constructor final statement + add to class and build + 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){ diff --git a/build.gradle b/build.gradle index e3baad885d..6dce08fcf3 100644 --- a/build.gradle +++ b/build.gradle @@ -308,8 +308,10 @@ project(":annotations"){ apply plugin: "java" dependencies{ + def arcVersion = "e287fdce0449a87fb15599c67b5167ac0273bcb6" + 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") } } diff --git a/core/src/mindustry/Vars.java b/core/src/mindustry/Vars.java index 0e15f79cc6..ab88d572bf 100644 --- a/core/src/mindustry/Vars.java +++ b/core/src/mindustry/Vars.java @@ -32,7 +32,6 @@ import java.util.*; import static arc.Core.settings; -@SuppressWarnings("unchecked") public class Vars implements Loadable{ /** Whether to load locales.*/ 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"; /** 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"; - /** 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"; /** list of built-in servers.*/ public static final Array defaultServers = Array.with(); diff --git a/gradle.properties b/gradle.properties index 4bccd74700..b74ceb8844 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=bf5f253d458e0b8bddf9efcc3642a644f4b48fb6 +archash=e287fdce0449a87fb15599c67b5167ac0273bcb6