Convert basic enum generators to JavaPoet, Block.java generation ported, but not block alternative classes yet

This commit is contained in:
jglrxavpok 2020-10-26 15:50:52 +01:00
parent 31114415cf
commit 2133e09527
16 changed files with 347 additions and 233 deletions

View File

@ -2,15 +2,14 @@ package net.minestom.codegen;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.squareup.javapoet.*;
import net.minestom.server.registry.Registries;
import net.minestom.server.utils.NamespaceID;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Collection;
import java.util.Objects;
import java.util.TreeSet;
import java.util.*;
public abstract class BasicEnumGenerator extends MinestomEnumGenerator<BasicEnumGenerator.Container> {
@ -56,21 +55,26 @@ public abstract class BasicEnumGenerator extends MinestomEnumGenerator<BasicEnum
@Override
protected void postWrite(EnumGenerator generator) {
ClassName className = ClassName.get(getPackageName(), getClassName());
ParameterSpec idParam = ParameterSpec.builder(TypeName.INT, "id").build();
ParameterSpec[] signature = new ParameterSpec[]{idParam};
if (linear) {
generator.addMethod("fromId", "(int id)", "static " + getClassName(),
"if(id >= 0 && id < values().length) {",
"\treturn values()[id];",
"}",
"return " + (defaultEntry == null ? "null" : identifier(defaultEntry)) + ";"
generator.addStaticMethod("fromId", signature, className, code -> {
code.beginControlFlow("if($N >= 0 && $N < values().length) {", idParam, idParam)
.addStatement("return values()[$N]", idParam)
.endControlFlow()
.addStatement("return " + (defaultEntry == null ? "null" : identifier(defaultEntry)));
}
);
} else {
generator.addMethod("fromId", "(int id)", "static " + getClassName(),
"for(" + getClassName() + " o : values()) {",
"\tif(o.getId() == id) {",
"\t\treturn o;",
"\t}",
"}",
"return " + (defaultEntry == null ? "null" : identifier(defaultEntry)) + ";"
generator.addStaticMethod("fromId", signature, className, code -> {
code.beginControlFlow("for($T o : values()) {")
.beginControlFlow("if(o.getId() == id) {")
.addStatement("return o")
.endControlFlow()
.endControlFlow()
.addStatement("return " + (defaultEntry == null ? "null" : identifier(defaultEntry)));
}
);
}
}
@ -80,24 +84,26 @@ public abstract class BasicEnumGenerator extends MinestomEnumGenerator<BasicEnum
}
@Override
protected void postGeneration() throws IOException {
protected List<JavaFile> postGeneration(Collection<Container> items) throws IOException {
return Collections.emptyList();
}
@Override
protected void prepare(EnumGenerator generator) {
generator.addClassAnnotation("@SuppressWarnings({\"deprecation\"})");
generator.addImport(Registries.class.getCanonicalName());
generator.addImport(NamespaceID.class.getCanonicalName());
generator.addClassAnnotation(AnnotationSpec.builder(SuppressWarnings.class).addMember("value", "{$S}", "deprecation").build());
ClassName registriesClass = ClassName.get(Registries.class);
if (linear) {
generator.setParams("String namespaceID");
generator.addMethod("getId", "()", "int", "return ordinal();");
generator.setParams(ParameterSpec.builder(ClassName.get(String.class), "namespaceID").build());
generator.addMethod("getId", new ParameterSpec[0], TypeName.INT, code -> code.addStatement("return ordinal()"));
} else {
generator.setParams("String namespaceID", "int id");
generator.addMethod("getId", "()", "int", "return id;");
generator.setParams(ParameterSpec.builder(ClassName.get(String.class), "namespaceID").build(), ParameterSpec.builder(TypeName.INT, "id").build());
generator.addMethod("getId", new ParameterSpec[0], TypeName.INT, code -> code.addStatement("return $N", "id"));
}
generator.addMethod("getNamespaceID", "()", "String", "return namespaceID;");
generator.addMethod("getNamespaceID", new ParameterSpec[0], ClassName.get(String.class), code -> code.addStatement("return $N", "namespaceID"));
generator.appendToConstructor("Registries." + CodeGenerator.decapitalize(getClassName()) + "s.put(NamespaceID.from(namespaceID), this);");
generator.appendToConstructor(code -> {
code.addStatement("$T." + CodeGenerator.decapitalize(getClassName()) + "s.put(NamespaceID.from($N), this)", registriesClass, "namespaceID");
});
}
@Override

View File

@ -1,6 +1,10 @@
package net.minestom.codegen;
import java.io.IOException;
import com.squareup.javapoet.JavaFile;
import org.slf4j.Logger;
import java.io.*;
import java.util.List;
/**
* Interface representing a code generator
@ -11,7 +15,19 @@ public interface CodeGenerator {
* Generates the Java code
* @return
*/
String generate() throws IOException;
List<JavaFile> generate() throws IOException;
default void generateTo(File targetFolder) throws IOException {
List<JavaFile> code = generate();
for(JavaFile file : code) {
// file.writeTo(targetFolder);
file.writeTo(System.out);
getLogger().debug("Writing file: "+file.packageName+"."+file.typeSpec.name);
}
}
Logger getLogger();
static String decapitalize(String text) {
char first = text.charAt(0);

View File

@ -1,165 +1,160 @@
package net.minestom.codegen;
import com.squareup.javapoet.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.lang.model.element.Modifier;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Consumer;
/**
* Helper class to generate a .java enum
*/
public class EnumGenerator implements CodeGenerator {
private final static Logger LOGGER = LoggerFactory.getLogger(EnumGenerator.class);
private static final String COMMENT = "//==============================\n// AUTOGENERATED BY " + EnumGenerator.class.getSimpleName() + "\n//==============================";
private final String enumName;
private String[] parameters;
private ParameterSpec[] parameters;
private List<Method> methods = new LinkedList<>();
private List<Instance> instances = new LinkedList<>();
private List<String> imports = new LinkedList<>();
private List<Field> hardcodedFields = new LinkedList<>();
private List<String> annotations = new LinkedList<>();
private List<AnnotationSpec> annotations = new LinkedList<>();
private String enumPackage;
private String staticBlock;
private StringBuilder constructorEnd = new StringBuilder();
private CodeBlock staticBlock;
private List<Consumer<CodeBlock.Builder>> constructorEnds = new LinkedList<>();
public EnumGenerator(String packageName, String enumName) {
this.enumPackage = packageName;
parameters = new String[0];
parameters = new ParameterSpec[0];
this.enumName = enumName;
}
public void setParams(String... parameters) {
public void setParams(ParameterSpec... parameters) {
this.parameters = parameters;
}
public void addMethod(String name, String signature, String returnType, String... lines) {
methods.add(new Method(true, name, signature, returnType, lines));
public void addMethod(String name, ParameterSpec[] signature, TypeName returnType, Consumer<CodeBlock.Builder> code) {
methods.add(new Method(true, name, signature, returnType, code, false));
}
public void addPackageMethod(String name, String signature, String returnType, String... lines) {
methods.add(new Method(false, name, signature, returnType, lines));
public void addVarargMethod(String name, ParameterSpec[] signature, TypeName returnType, Consumer<CodeBlock.Builder> code) {
methods.add(new Method(true, name, signature, returnType, code, true));
}
public void addStaticMethod(String name, ParameterSpec[] signature, TypeName returnType, Consumer<CodeBlock.Builder> code) {
methods.add(new Method(false, name, signature, returnType, code, false));
}
public void addInstance(String name, Object... parameters) {
instances.add(new Instance(name, parameters));
}
public String generate() {
StringBuilder builder = new StringBuilder();
builder.append(COMMENT);
builder.append("\npackage ").append(enumPackage).append(";\n");
for (String imp : imports) {
builder.append("import ").append(imp).append(";\n");
}
for (String annotation : annotations) {
builder.append(annotation).append("\n");
}
builder.append("\npublic enum ").append(enumName).append(" {\n");
public List<JavaFile> generate() {
TypeSpec.Builder enumClass = TypeSpec.enumBuilder(ClassName.get(enumPackage, enumName)).addModifiers(Modifier.PUBLIC);
// generate instances
for (Instance instance : instances) {
builder.append("\t");
builder.append(instance.name).append("(");
Object[] objects = instance.parameters;
for (int i = 0; i < objects.length; i++) {
Object param = objects[i];
enumClass.addJavadoc(COMMENT);
for(AnnotationSpec annotation : annotations) {
enumClass.addAnnotation(annotation);
}
for(Instance instance : instances) {
StringBuilder format = new StringBuilder();
for (int i = 0; i < instance.parameters.length; i++) {
if (i != 0) {
builder.append(", ");
format.append(", ");
}
builder.append(param.toString());
format.append("$L");
}
builder.append("),\n");
}
builder.append(";\n");
if (staticBlock != null) {
builder.append("\n\tstatic {\n");
builder.append(staticBlock);
builder.append("\t}\n\n");
// generate instances
TypeSpec arguments = TypeSpec.anonymousClassBuilder(format.toString(), instance.parameters).build();
enumClass.addEnumConstant(instance.name, arguments);
}
if(staticBlock != null) {
enumClass.addStaticBlock(staticBlock);
}
// generate properties & constructor
if (parameters.length != 0) {
// properties
for (String property : parameters) {
builder.append("\t");
builder.append("private ").append(property).append(";\n");
for (ParameterSpec property : parameters) {
enumClass.addField(FieldSpec.builder(property.type, property.name)
.addModifiers(Modifier.PRIVATE)
.addAnnotations(property.annotations)
.build());
}
builder.append("\n");
// hard coded fields
for (Field hardcoded : hardcodedFields) {
builder.append("\tprivate ").append(hardcoded.type).append(" ").append(hardcoded.name).append(" = ").append(hardcoded.value).append(";");
builder.append("\n");
enumClass.addField(FieldSpec.builder(hardcoded.type, hardcoded.name)
.initializer("$L", hardcoded.value)
.addModifiers(Modifier.PRIVATE)
.build());
}
// constructor
builder.append("\t");
builder.append(enumName).append("(");
MethodSpec.Builder constructorBuilder = MethodSpec.constructorBuilder();
for (int i = 0; i < parameters.length; i++) {
if (i != 0) {
builder.append(", ");
}
builder.append(parameters[i]);
ParameterSpec param = parameters[i];
constructorBuilder.addParameter(param);
// property assignment
constructorBuilder.addStatement("this.$N = $N", param.name, param.name);
}
builder.append(") {\n");
// property assignment
for (String property : parameters) {
String[] parts = property.split(" ");
String type = parts[0];
String name = parts[1];
builder.append("\t\t");
builder.append("this.").append(name).append(" = ").append(name).append(";\n");
}
builder.append(constructorEnd);
builder.append("\t}\n");
CodeBlock.Builder generatorEnd = CodeBlock.builder();
constructorEnds.forEach(b -> b.accept(generatorEnd));
constructorBuilder.addCode(generatorEnd.build());
enumClass.addMethod(constructorBuilder.build());
}
// generate methods
for (Method m : methods) {
builder.append("\n");
builder.append("\t");
if (m.isPublic) {
builder.append("public ");
MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(m.name);
if (m.isStatic) {
methodBuilder.addModifiers(Modifier.STATIC);
}
builder.append(m.returnType).append(" ").append(m.name).append(m.signature).append(" {\n");
for (String line : m.lines) {
builder.append("\t\t").append(line).append("\n");
methodBuilder.addModifiers(Modifier.PUBLIC);
methodBuilder.returns(m.returnType);
if(m.vararg) {
methodBuilder.varargs(true);
}
for(ParameterSpec parameter : m.signature) {
methodBuilder.addParameter(parameter);
}
builder.append("\t}\n");
CodeBlock.Builder builder = CodeBlock.builder();
m.code.accept(builder);
methodBuilder.addCode(builder.build());
enumClass.addMethod(methodBuilder.build());
}
builder.append("}\n");
return builder.toString();
JavaFile file = JavaFile.builder(enumPackage, enumClass.build())
.skipJavaLangImports(true)
.indent(" ")
.build();
return Collections.singletonList(file);
}
public void setEnumPackage(String enumPackage) {
this.enumPackage = enumPackage;
}
public void addImport(String canonicalName) {
imports.add(canonicalName);
}
public void setStaticInitBlock(String staticBlock) {
public void setStaticInitBlock(CodeBlock staticBlock) {
this.staticBlock = staticBlock;
}
public void appendToConstructor(String... lines) {
for (String line : lines) {
constructorEnd.append("\t\t").append(line).append("\n");
}
public void appendToConstructor(Consumer<CodeBlock.Builder> constructorEnding) {
constructorEnds.add(constructorEnding);
}
public void addHardcodedField(String type, String name, String value) {
public void addHardcodedField(TypeName type, String name, String value) {
hardcodedFields.add(new Field(type, name, value));
}
public void addClassAnnotation(String annotation) {
public void addClassAnnotation(AnnotationSpec annotation) {
annotations.add(annotation);
}
@ -171,28 +166,35 @@ public class EnumGenerator implements CodeGenerator {
return enumName;
}
private static class Method {
private final boolean isPublic;
private String name;
private String signature;
private String returnType;
private String[] lines;
@Override
public Logger getLogger() {
return LOGGER;
}
private Method(boolean isPublic, String name, String signature, String returnType, String[] lines) {
this.isPublic = isPublic;
private static class Method {
private final boolean isStatic;
private String name;
private ParameterSpec[] signature;
private TypeName returnType;
private Consumer<CodeBlock.Builder> code;
private boolean vararg;
private Method(boolean isStatic, String name, ParameterSpec[] signature, TypeName returnType, Consumer<CodeBlock.Builder> code, boolean vararg) {
this.isStatic = isStatic;
this.name = name;
this.signature = signature;
this.returnType = returnType;
this.lines = lines;
this.code = code;
this.vararg = vararg;
}
}
private static class Field {
private String type;
private TypeName type;
private String name;
private String value;
public Field(String type, String name, String value) {
public Field(TypeName type, String name, String value) {
this.type = type;
this.name = name;
this.value = value;

View File

@ -1,12 +1,12 @@
package net.minestom.codegen;
import com.google.gson.Gson;
import net.minestom.codegen.blocks.BlockEnumGenerator;
import com.squareup.javapoet.JavaFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
/**
@ -19,28 +19,6 @@ public abstract class MinestomEnumGenerator<Container> implements CodeGenerator
public static final String PRISMARINE_JS_DATA_PATHS = "prismarine-minecraft-data/data/dataPaths.json";
public static final String BURGER_URL_BASE_URL = "https://pokechu22.github.io/Burger/";
/**
* Generate the given enum inside the targetFolder. This generator will create subfolders if needed to match the package name.
* (consider targetFolder as a root folder for generation)
* @param targetFolder
*/
public void generateTo(File targetFolder) throws IOException {
String code = generate();
String folder = getRelativeFolderPath();
File parentFolder = new File(targetFolder, folder);
if(!parentFolder.exists()) {
parentFolder.mkdirs();
}
LOGGER.debug("Writing enum to file: "+parentFolder+"/"+getClassName()+".java");
try(Writer writer = new BufferedWriter(new FileWriter(new File(parentFolder, getClassName()+".java")))) {
writer.write(code);
}
LOGGER.debug("Post generation tasks...");
postGeneration();
}
/**
* Package name with '.' replaced by '/'
* @return
@ -50,7 +28,7 @@ public abstract class MinestomEnumGenerator<Container> implements CodeGenerator
}
@Override
public String generate() throws IOException {
public List<JavaFile> generate() throws IOException {
EnumGenerator generator = new EnumGenerator(getPackageName(), getClassName());
prepare(generator);
Collection<Container> items = compile();
@ -59,7 +37,9 @@ public abstract class MinestomEnumGenerator<Container> implements CodeGenerator
}
postWrite(generator);
return generator.generate();
List<JavaFile> list = new LinkedList<>(generator.generate());
list.addAll(postGeneration(items));
return list;
}
/**
@ -70,8 +50,9 @@ public abstract class MinestomEnumGenerator<Container> implements CodeGenerator
/**
* Called after code generation (only if generated through a {@link #generateTo(File)} call). Can be used to generate additional files
* @param items
*/
protected abstract void postGeneration() throws IOException;
protected abstract List<JavaFile> postGeneration(Collection<Container> items) throws IOException;
/**
* Package in which to generate the enum

View File

@ -22,7 +22,9 @@ import org.slf4j.LoggerFactory;
import javax.lang.model.element.Modifier;
import java.io.*;
import java.lang.annotation.Annotation;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import static net.minestom.codegen.MinestomEnumGenerator.DEFAULT_TARGET_PATH;
@ -47,7 +49,7 @@ public class RegistriesGenerator implements CodeGenerator {
};
@Override
public String generate() throws IOException {
public List<JavaFile> generate() throws IOException {
TypeSpec.Builder registriesClass = TypeSpec.classBuilder(ClassName.get("net.minestom.server.registry", "Registries"))
.addModifiers(Modifier.FINAL, Modifier.PUBLIC)
.addJavadoc("AUTOGENERATED");
@ -138,9 +140,7 @@ public class RegistriesGenerator implements CodeGenerator {
.indent(" ")
.skipJavaLangImports(true)
.build();
StringWriter strWriter = new StringWriter();
file.writeTo(strWriter);
return strWriter.toString();
return Collections.singletonList(file);
}
public static void main(String[] args) throws IOException {
@ -172,17 +172,8 @@ public class RegistriesGenerator implements CodeGenerator {
new RegistriesGenerator().generateTo(targetFolder);
}
private void generateTo(File targetFolder) throws IOException {
String code = generate();
String folder = "net/minestom/server/registry";
File parentFolder = new File(targetFolder, folder);
if (!parentFolder.exists()) {
parentFolder.mkdirs();
}
LOGGER.debug("Writing to file: " + parentFolder + "/Registries.java");
try (Writer writer = new BufferedWriter(new FileWriter(new File(parentFolder, "Registries.java")))) {
writer.write(code);
}
@Override
public Logger getLogger() {
return LOGGER;
}
}

View File

@ -4,6 +4,7 @@ import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.squareup.javapoet.*;
import net.minestom.codegen.EnumGenerator;
import net.minestom.codegen.MinestomEnumGenerator;
import net.minestom.codegen.PrismarinePaths;
@ -11,6 +12,8 @@ import net.minestom.server.instance.block.BlockAlternative;
import net.minestom.server.registry.Registries;
import net.minestom.server.registry.ResourceGatherer;
import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -30,7 +33,7 @@ public class BlockEnumGenerator extends MinestomEnumGenerator<BlockContainer> {
private final String targetVersion;
private final File targetFolder;
private StringBuilder staticBlock = new StringBuilder();
private CodeBlock.Builder staticBlock = CodeBlock.builder();
private Map<String, String> subclassContents = new HashMap<>();
@ -243,53 +246,60 @@ public class BlockEnumGenerator extends MinestomEnumGenerator<BlockContainer> {
@Override
protected void prepare(EnumGenerator generator) {
String className = getClassName();
generator.addClassAnnotation("@SuppressWarnings({\"deprecation\"})");
generator.addImport(Registries.class.getCanonicalName());
generator.addImport(NamespaceID.class.getCanonicalName());
generator.addImport(List.class.getCanonicalName());
generator.addImport(ArrayList.class.getCanonicalName());
generator.addImport(Arrays.class.getCanonicalName());
generator.addImport(generator.getPackage() + ".states.*");
generator.addHardcodedField("List<BlockAlternative>", "alternatives", "new ArrayList<BlockAlternative>()");
ClassName className = ClassName.get(getPackageName(), getClassName());
generator.addClassAnnotation(AnnotationSpec.builder(SuppressWarnings.class).addMember("value", "{$S}", "deprecation").build());
generator.setParams("String namespaceID", "short defaultID", "double hardness", "double resistance", "boolean isAir", "boolean isSolid", "NamespaceID blockEntity", "boolean singleState");
generator.addMethod("getBlockId", "()", "short", "return defaultID;");
generator.addMethod("getName", "()", "String", "return namespaceID;");
generator.addMethod("isAir", "()", "boolean", "return isAir;");
generator.addMethod("hasBlockEntity", "()", "boolean", "return blockEntity != null;");
generator.addMethod("getBlockEntityName", "()", "NamespaceID", "return blockEntity;");
generator.addMethod("isSolid", "()", "boolean", "return isSolid;");
generator.addMethod("isLiquid", "()", "boolean", "return this == WATER || this == LAVA;");
generator.addMethod("getHardness", "()", "double", "return hardness;");
generator.addMethod("getResistance", "()", "double", "return resistance;");
generator.addMethod("breaksInstantaneously", "()", "boolean", "return hardness == 0;");
generator.addMethod("addBlockAlternative", "(BlockAlternative alternative)", "void",
"alternatives.add(alternative);",
"BlockArray.blocks[alternative.getId()] = this;"
generator.setParams(
ParameterSpec.builder(String.class, "namespaceID").addAnnotation(NotNull.class).build(),
ParameterSpec.builder(TypeName.DOUBLE, "hardness").build(),
ParameterSpec.builder(TypeName.DOUBLE, "resistance").build(),
ParameterSpec.builder(TypeName.BOOLEAN, "isAir").build(),
ParameterSpec.builder(TypeName.BOOLEAN, "isSolid").build(),
ParameterSpec.builder(NamespaceID.class, "blockEntity").addAnnotation(Nullable.class).build(),
ParameterSpec.builder(TypeName.BOOLEAN, "singleState").build()
);
String[] withPropertiesLines = {
"for (BlockAlternative alt : alternatives) {",
"\tif (Arrays.equals(alt.getProperties(), properties)) {",
"\t\treturn alt.getId();",
"\t}",
"}",
"return defaultID;"
};
generator.addMethod("getAlternative", "(short blockId)", "BlockAlternative",
"for (BlockAlternative alt : alternatives) {",
"\tif (alt.getId() == blockId) {",
"\t\treturn alt;",
"\t}",
"}",
"return null;");
generator.addMethod("getAlternatives", "()", "List<BlockAlternative>", "return alternatives;");
generator.addMethod("withProperties", "(String... properties)", "short", withPropertiesLines);
generator.addMethod("fromStateId", "(short blockStateId)", "static " + className, "return BlockArray.blocks[blockStateId];");
generator.appendToConstructor("if(singleState) {");
generator.appendToConstructor("\taddBlockAlternative(new BlockAlternative(defaultID));");
generator.appendToConstructor("}");
generator.appendToConstructor("Registries.blocks.put(NamespaceID.from(namespaceID), this);");
generator.addHardcodedField(ParameterizedTypeName.get(List.class, BlockAlternative.class), "alternatives", "new ArrayList<>()");
generator.addMethod("getBlockId", new ParameterSpec[0], TypeName.SHORT, code -> code.addStatement("return defaultID"));
generator.addMethod("getName", new ParameterSpec[0], ClassName.get(String.class), code -> code.addStatement("return namespaceID"));
generator.addMethod("isAir", new ParameterSpec[0], TypeName.BOOLEAN, code -> code.addStatement("return isAir"));
generator.addMethod("hasBlockEntity", new ParameterSpec[0], TypeName.BOOLEAN, code -> code.addStatement("return blockEntity != null"));
generator.addMethod("getBlockEntityName", new ParameterSpec[0], ClassName.get(NamespaceID.class), code -> code.addStatement("return blockEntity"));
generator.addMethod("isSolid", new ParameterSpec[0], TypeName.BOOLEAN, code -> code.addStatement("return isSolid"));
generator.addMethod("isLiquid", new ParameterSpec[0], TypeName.BOOLEAN, code -> code.addStatement("return this == WATER || this == LAVA"));
generator.addMethod("getHardness", new ParameterSpec[0], TypeName.DOUBLE, code -> code.addStatement("return hardness"));
generator.addMethod("getResistance", new ParameterSpec[0], TypeName.DOUBLE, code -> code.addStatement("return resistance"));
generator.addMethod("breaksInstantaneously", new ParameterSpec[0], TypeName.BOOLEAN, code -> code.addStatement("return hardness == 0"));
generator.addMethod("addBlockAlternative", new ParameterSpec[]{ParameterSpec.builder(BlockAlternative.class, "alternative").build()}, TypeName.VOID, code -> {
code.addStatement("alternatives.add(alternative)")
.addStatement("$T.blocks[alternative.getId()] = this", ClassName.get("net.minestom.server.instance.block", "BlockArray"));
});
generator.addMethod("getAlternative", new ParameterSpec[]{ParameterSpec.builder(TypeName.SHORT, "blockId").build()}, ClassName.get(BlockAlternative.class), code -> {
code.beginControlFlow("for($T alt : alternatives)", BlockAlternative.class)
.beginControlFlow("if(alt.getId() == blockId)")
.addStatement("return alt")
.endControlFlow()
.endControlFlow()
.addStatement("return null");
});
generator.addMethod("getAlternatives", new ParameterSpec[0], ParameterizedTypeName.get(List.class, BlockAlternative.class), code -> code.addStatement("return alternatives"));
generator.addVarargMethod("withProperties", new ParameterSpec[]{ParameterSpec.builder(String[].class, "properties").build()}, TypeName.SHORT, code -> {
code.beginControlFlow("for($T alt : alternatives)", BlockAlternative.class)
.beginControlFlow("if(Arrays.equals(alt.getProperties(), properties))")
.addStatement("return alt.getId()")
.endControlFlow()
.endControlFlow()
.addStatement("return defaultID");
});
generator.addStaticMethod("fromStateId", new ParameterSpec[]{ParameterSpec.builder(TypeName.SHORT, "blockStateId").build()}, className, code -> code.addStatement("return $T.blocks[blockStateId]", ClassName.get("net.minestom.server.instance.block", "BlockArray")));
generator.appendToConstructor(code -> {
code.beginControlFlow("if(singleState)")
.addStatement("addBlockAlternative(new BlockAlternative(defaultID))")
.endControlFlow()
.addStatement("$T.blocks.put($T.from(namespaceID), this)", Registries.class, NamespaceID.class);
});
}
@Override
@ -309,6 +319,7 @@ public class BlockEnumGenerator extends MinestomEnumGenerator<BlockContainer> {
// do not add alternative for default states. This will be added by default inside the constructor
if (block.getStates().size() > 1) {
StringBuilder subclass = new StringBuilder();
// TODO: convert to Javapoet
for (BlockContainer.BlockState state : block.getStates()) {
if (state == block.getDefaultState())
continue;
@ -329,12 +340,12 @@ public class BlockEnumGenerator extends MinestomEnumGenerator<BlockContainer> {
String blockName = snakeCaseToCapitalizedCamelCase(block.getId().getPath());
blockName = blockName.replace("_", "");
subclassContents.put(blockName, subclass.toString());
staticBlock.append("\t\t").append(blockName).append(".initStates();\n");
staticBlock.addStatement("$T.initStates()", ClassName.get(getPackageName()+".states", blockName));
}
}
@Override
protected void postGeneration() throws IOException {
protected List<JavaFile> postGeneration(Collection<BlockContainer> items) throws IOException {
File classFolder = new File(targetFolder, getRelativeFolderPath());
if (!classFolder.exists()) {
classFolder.mkdirs();
@ -380,15 +391,23 @@ public class BlockEnumGenerator extends MinestomEnumGenerator<BlockContainer> {
classContents.append("\t}\n");
classContents.append("}\n");
try (Writer writer = new BufferedWriter(new FileWriter(new File(subclassFolder, subclass + ".java")))) {
/* try (Writer writer = new BufferedWriter(new FileWriter(new File(subclassFolder, subclass + ".java")))) {
writer.write(classContents.toString());
}
}*/
LOGGER.debug("\t\t - Done");
}
// TODO: subclasses
return Collections.emptyList();
}
@Override
protected void postWrite(EnumGenerator generator) {
generator.setStaticInitBlock(staticBlock.toString());
generator.setStaticInitBlock(staticBlock.build());
}
@Override
public Logger getLogger() {
return LOGGER;
}
}

View File

@ -1,12 +1,18 @@
package net.minestom.codegen.enchantment;
import net.minestom.codegen.BasicEnumGenerator;
import net.minestom.codegen.stats.StatsEnumGenerator;
import net.minestom.server.registry.ResourceGatherer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
public class EnchantmentEnumGenerator extends BasicEnumGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(EnchantmentEnumGenerator.class);
public static void main(String[] args) throws IOException {
String targetVersion;
if(args.length < 1) {
@ -53,4 +59,9 @@ public class EnchantmentEnumGenerator extends BasicEnumGenerator {
public String getClassName() {
return "Enchantment";
}
@Override
public Logger getLogger() {
return LOGGER;
}
}

View File

@ -1,12 +1,18 @@
package net.minestom.codegen.entitytypes;
import net.minestom.codegen.BasicEnumGenerator;
import net.minestom.codegen.stats.StatsEnumGenerator;
import net.minestom.server.registry.ResourceGatherer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
public class EntityTypeEnumGenerator extends BasicEnumGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(EntityTypeEnumGenerator.class);
public static void main(String[] args) throws IOException {
String targetVersion;
if(args.length < 1) {
@ -53,4 +59,9 @@ public class EntityTypeEnumGenerator extends BasicEnumGenerator {
public String getClassName() {
return "EntityType";
}
@Override
public Logger getLogger() {
return LOGGER;
}
}

View File

@ -1,12 +1,18 @@
package net.minestom.codegen.fluids;
import net.minestom.codegen.BasicEnumGenerator;
import net.minestom.codegen.stats.StatsEnumGenerator;
import net.minestom.server.registry.ResourceGatherer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
public class FluidEnumGenerator extends BasicEnumGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(FluidEnumGenerator.class);
public static void main(String[] args) throws IOException {
String targetVersion;
if(args.length < 1) {
@ -53,4 +59,9 @@ public class FluidEnumGenerator extends BasicEnumGenerator {
public String getClassName() {
return "Fluid";
}
@Override
public Logger getLogger() {
return LOGGER;
}
}

View File

@ -3,6 +3,8 @@ package net.minestom.codegen.items;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.squareup.javapoet.AnnotationSpec;
import com.squareup.javapoet.JavaFile;
import net.minestom.codegen.EnumGenerator;
import net.minestom.codegen.MinestomEnumGenerator;
import net.minestom.codegen.PrismarinePaths;
@ -15,10 +17,7 @@ import org.slf4j.LoggerFactory;
import java.io.*;
import java.net.URL;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.TreeSet;
import java.util.*;
/**
* Generates a Material enum containing all data about items
@ -140,11 +139,8 @@ public class ItemEnumGenerator extends MinestomEnumGenerator<ItemContainer> {
@Override
protected void prepare(EnumGenerator generator) {
String className = getClassName();
generator.addImport(Block.class.getCanonicalName());
generator.addImport(Registries.class.getCanonicalName());
generator.addImport(NamespaceID.class.getCanonicalName());
generator.addClassAnnotation("@SuppressWarnings({\"deprecation\"})");
generator.setParams("String namespaceID", "int maxDefaultStackSize", "Block correspondingBlock");
generator.addClassAnnotation(AnnotationSpec.builder(SuppressWarnings.class).addMember("value", "{$S}", "deprecation").build());
/*generator.setParams("String namespaceID", "int maxDefaultStackSize", "Block correspondingBlock");
generator.appendToConstructor("Registries.materials.put(NamespaceID.from(namespaceID), this);");
generator.addMethod("getId", "()", "short", "return (short)ordinal();");
@ -217,7 +213,7 @@ public class ItemEnumGenerator extends MinestomEnumGenerator<ItemContainer> {
" return true;\n" +
" }\n" +
"\n" +
" return isFood();");
" return isFood();");*/
}
@Override
@ -231,10 +227,16 @@ public class ItemEnumGenerator extends MinestomEnumGenerator<ItemContainer> {
}
@Override
protected void postGeneration() throws IOException {
protected List<JavaFile> postGeneration(Collection<ItemContainer> items) throws IOException {
return Collections.emptyList();
}
@Override
protected void postWrite(EnumGenerator generator) {
}
@Override
public Logger getLogger() {
return LOGGER;
}
}

View File

@ -1,12 +1,18 @@
package net.minestom.codegen.particles;
import net.minestom.codegen.BasicEnumGenerator;
import net.minestom.codegen.stats.StatsEnumGenerator;
import net.minestom.server.registry.ResourceGatherer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
public class ParticleEnumGenerator extends BasicEnumGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(ParticleEnumGenerator.class);
public static void main(String[] args) throws IOException {
String targetVersion;
if(args.length < 1) {
@ -53,4 +59,9 @@ public class ParticleEnumGenerator extends BasicEnumGenerator {
public String getClassName() {
return "Particle";
}
@Override
public Logger getLogger() {
return LOGGER;
}
}

View File

@ -1,12 +1,18 @@
package net.minestom.codegen.potions;
import net.minestom.codegen.BasicEnumGenerator;
import net.minestom.codegen.stats.StatsEnumGenerator;
import net.minestom.server.registry.ResourceGatherer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
public class PotionEffectEnumGenerator extends BasicEnumGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(PotionEffectEnumGenerator.class);
public static void main(String[] args) throws IOException {
String targetVersion;
if (args.length < 1) {
@ -53,4 +59,9 @@ public class PotionEffectEnumGenerator extends BasicEnumGenerator {
public String getClassName() {
return "PotionEffect";
}
@Override
public Logger getLogger() {
return LOGGER;
}
}

View File

@ -1,12 +1,18 @@
package net.minestom.codegen.potions;
import net.minestom.codegen.BasicEnumGenerator;
import net.minestom.codegen.stats.StatsEnumGenerator;
import net.minestom.server.registry.ResourceGatherer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
public class PotionEnumGenerator extends BasicEnumGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(PotionEnumGenerator.class);
public static void main(String[] args) throws IOException {
String targetVersion;
if (args.length < 1) {
@ -53,4 +59,9 @@ public class PotionEnumGenerator extends BasicEnumGenerator {
public String getClassName() {
return "PotionType";
}
@Override
public Logger getLogger() {
return LOGGER;
}
}

View File

@ -1,12 +1,18 @@
package net.minestom.codegen.sounds;
import net.minestom.codegen.BasicEnumGenerator;
import net.minestom.codegen.stats.StatsEnumGenerator;
import net.minestom.server.registry.ResourceGatherer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
public class SoundEnumGenerator extends BasicEnumGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(SoundEnumGenerator.class);
public static void main(String[] args) throws IOException {
String targetVersion;
if(args.length < 1) {
@ -53,4 +59,9 @@ public class SoundEnumGenerator extends BasicEnumGenerator {
public String getClassName() {
return "Sound";
}
@Override
public Logger getLogger() {
return LOGGER;
}
}

View File

@ -2,11 +2,16 @@ package net.minestom.codegen.stats;
import net.minestom.codegen.BasicEnumGenerator;
import net.minestom.server.registry.ResourceGatherer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
public class BiomesEnumGenerator extends BasicEnumGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(BiomesEnumGenerator.class);
public static void main(String[] args) throws IOException {
String targetVersion;
if(args.length < 1) {
@ -53,4 +58,9 @@ public class BiomesEnumGenerator extends BasicEnumGenerator {
public String getClassName() {
return "Biome";
}
@Override
public Logger getLogger() {
return LOGGER;
}
}

View File

@ -2,11 +2,16 @@ package net.minestom.codegen.stats;
import net.minestom.codegen.BasicEnumGenerator;
import net.minestom.server.registry.ResourceGatherer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
public class StatsEnumGenerator extends BasicEnumGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(StatsEnumGenerator.class);
public static void main(String[] args) throws IOException {
String targetVersion;
if(args.length < 1) {
@ -53,4 +58,9 @@ public class StatsEnumGenerator extends BasicEnumGenerator {
public String getClassName() {
return "StatisticType";
}
@Override
public Logger getLogger() {
return LOGGER;
}
}