This commit is contained in:
Anuken
2020-06-26 14:27:26 -04:00
parent eabc5c15c7
commit fdf7c88083
228 changed files with 1219 additions and 1163 deletions

View File

@@ -136,6 +136,7 @@ public class EntityProcess extends BaseProcessor{
if(!signatures.contains(cname + "()")){
inter.addMethod(MethodSpec.methodBuilder(cname).addModifiers(Modifier.ABSTRACT, Modifier.PUBLIC)
.addAnnotations(Seq.with(field.annotations()).select(a -> a.toString().contains("Null")).map(AnnotationSpec::get))
//.addAnnotation(Deprecated.class) //TODO undeprecate
.addJavadoc(field.doc() == null ? "" : field.doc())
.returns(field.tname()).build());
}
@@ -146,6 +147,7 @@ public class EntityProcess extends BaseProcessor{
inter.addMethod(MethodSpec.methodBuilder(cname).addModifiers(Modifier.ABSTRACT, Modifier.PUBLIC)
.addJavadoc(field.doc() == null ? "" : field.doc())
.addParameter(ParameterSpec.builder(field.tname(), field.name())
//.addAnnotation(Deprecated.class) //TODO undeprecate
.addAnnotations(Seq.with(field.annotations())
.select(a -> a.toString().contains("Null")).map(AnnotationSpec::get)).build()).build());
}
@@ -185,7 +187,7 @@ public class EntityProcess extends BaseProcessor{
}
//add interfaces
for(Stype type : depends){
for(Stype type : deps){
base.addSuperinterface(tname(packageName, interfaceName(type)));
}
@@ -222,9 +224,13 @@ public class EntityProcess extends BaseProcessor{
return result;
});
//representative component type
Stype repr = types.first();
String groupType = repr.annotation(Component.class).base() ? baseName(repr) : interfaceName(repr);
boolean collides = an.collide();
groupDefs.add(new GroupDefinition(group.name().startsWith("g") ? group.name().substring(1) : group.name(),
ClassName.bestGuess(packageName + "." + interfaceName(types.first())), types, an.spatial(), an.mapping(), collides));
ClassName.bestGuess(packageName + "." + groupType), types, an.spatial(), an.mapping(), collides));
}
ObjectMap<String, Selement> usedNames = new ObjectMap<>();
@@ -232,33 +238,9 @@ public class EntityProcess extends BaseProcessor{
//look at each definition
for(Selement<?> type : allDefs){
EntityDef ann = type.annotation(EntityDef.class);
boolean isFinal = ann.isFinal();
if(type.isType() && (!type.name().endsWith("Def") && !type.name().endsWith("Comp"))){
err("All entity def names must end with 'Def'/'Comp'", type.e);
}
String name = type.isType() ?
type.name().replace("Def", "Entity").replace("Comp", "Entity") :
createName(type);
//skip double classes
if(usedNames.containsKey(name)){
extraNames.get(usedNames.get(name), ObjectSet::new).add(type.name());
continue;
}
usedNames.put(name, type);
extraNames.get(type, ObjectSet::new).add(name);
if(!type.isType()){
extraNames.get(type, ObjectSet::new).add(type.name());
}
TypeSpec.Builder builder = TypeSpec.classBuilder(name).addModifiers(Modifier.PUBLIC);
if(isFinal) builder.addModifiers(Modifier.FINAL);
//all component classes (not interfaces)
Seq<Stype> components = allComponents(type);
Seq<GroupDefinition> groups = groupDefs.select(g -> (!g.components.isEmpty() && !g.components.contains(s -> !components.contains(s))) || g.manualInclusions.contains(type));
@@ -278,8 +260,37 @@ public class EntityProcess extends BaseProcessor{
//whether the main class is the base itself
boolean typeIsBase = baseClassType != null && type.has(Component.class) && type.annotation(Component.class).base();
if(type.isType() && (!type.name().endsWith("Def") && !type.name().endsWith("Comp"))){
err("All entity def names must end with 'Def'/'Comp'", type.e);
}
String name = type.isType() ?
type.name().replace("Def", "").replace("Comp", "") :
createName(type);
//check for type name conflicts
if(!typeIsBase && baseClass != null && name.equals(baseName(baseClassType))){
name += "Entity";
}
//skip double classes
if(usedNames.containsKey(name)){
extraNames.get(usedNames.get(name), ObjectSet::new).add(type.name());
continue;
}
usedNames.put(name, type);
extraNames.get(type, ObjectSet::new).add(name);
if(!type.isType()){
extraNames.get(type, ObjectSet::new).add(type.name());
}
TypeSpec.Builder builder = TypeSpec.classBuilder(name).addModifiers(Modifier.PUBLIC);
if(isFinal && !typeIsBase) builder.addModifiers(Modifier.FINAL);
//add serialize() boolean
builder.addMethod(MethodSpec.methodBuilder("serialize").addModifiers(Modifier.PUBLIC, Modifier.FINAL).returns(boolean.class).addStatement("return " + ann.serialize()).build());
builder.addMethod(MethodSpec.methodBuilder("serialize").addModifiers(Modifier.PUBLIC).returns(boolean.class).addStatement("return " + ann.serialize()).build());
//all SyncField fields
Seq<Svar> syncedFields = new Seq<>();
@@ -401,7 +412,7 @@ public class EntityProcess extends BaseProcessor{
//build method using same params/returns
MethodSpec.Builder mbuilder = MethodSpec.methodBuilder(first.name()).addModifiers(first.is(Modifier.PRIVATE) ? Modifier.PRIVATE : Modifier.PUBLIC);
if(isFinal || entry.value.contains(s -> s.has(Final.class))) mbuilder.addModifiers(Modifier.FINAL);
//if(isFinal || entry.value.contains(s -> s.has(Final.class))) mbuilder.addModifiers(Modifier.FINAL);
if(entry.value.contains(s -> s.has(CallSuper.class))) mbuilder.addAnnotation(CallSuper.class); //add callSuper here if necessary
if(first.is(Modifier.STATIC)) mbuilder.addModifiers(Modifier.STATIC);
mbuilder.addTypeVariables(first.typeVariables().map(TypeVariableName::get));
@@ -536,7 +547,7 @@ public class EntityProcess extends BaseProcessor{
.returns(tname(packageName + "." + name))
.addStatement(ann.pooled() ? "return Pools.obtain($L.class, " +name +"::new)" : "return new $L()", name).build());
definitions.add(new EntityDefinition(packageName + "." + name, builder, type, baseClass, components, groups, allFieldSpecs));
definitions.add(new EntityDefinition(packageName + "." + name, builder, type, typeIsBase ? null : baseClass, components, groups, allFieldSpecs));
}
//generate groups
@@ -686,12 +697,12 @@ public class EntityProcess extends BaseProcessor{
//getter
if(!method.isVoid()){
def.builder.addMethod(MethodSpec.overriding(method.e).addStatement("return " + var).addModifiers(Modifier.FINAL).build());
def.builder.addMethod(MethodSpec.overriding(method.e).addStatement("return " + var).build());
}
//setter
if(method.isVoid() && !Seq.with(field.annotations).contains(f -> f.type.toString().equals("@mindustry.annotations.Annotations.ReadOnly"))){
def.builder.addMethod(MethodSpec.overriding(method.e).addModifiers(Modifier.FINAL).addStatement("this." + var + " = " + var).build());
def.builder.addMethod(MethodSpec.overriding(method.e).addStatement("this." + var + " = " + var).build());
}
}
}
@@ -709,6 +720,11 @@ public class EntityProcess extends BaseProcessor{
Seq<Smethod> methods = dependencies.flatMap(Stype::methods);
methods.sortComparing(Object::toString);
//optionally add superclass
Stype superclass = dependencies.map(this::interfaceToComp).find(s -> s != null && s.annotation(Component.class).base());
//use the base type when the interface being emulated has a base
TypeName type = superclass != null && interfaceToComp(interf).annotation(Component.class).base() ? tname(baseName(superclass)) : interf.tname();
//used method signatures
ObjectSet<String> signatures = new ObjectSet<>();
@@ -719,6 +735,7 @@ public class EntityProcess extends BaseProcessor{
.addModifiers(Modifier.FINAL);
nullBuilder.addSuperinterface(interf.tname());
if(superclass != null) nullBuilder.superclass(tname(baseName(superclass)));
for(Smethod method : methods){
String signature = method.toString();
@@ -726,6 +743,7 @@ public class EntityProcess extends BaseProcessor{
Stype compType = interfaceToComp(method.type());
MethodSpec.Builder builder = MethodSpec.overriding(method.e).addModifiers(Modifier.PUBLIC, Modifier.FINAL);
builder.addAnnotation(OverrideCallSuper.class); //just in case
if(!method.isVoid()){
if(method.name().equals("isNull")){
@@ -749,7 +767,7 @@ public class EntityProcess extends BaseProcessor{
signatures.add(signature);
}
nullsBuilder.addField(FieldSpec.builder(interf.cname(), Strings.camelize(baseName)).initializer("new " + className + "()").addModifiers(Modifier.FINAL, Modifier.STATIC, Modifier.PUBLIC).build());
nullsBuilder.addField(FieldSpec.builder(type, Strings.camelize(baseName)).initializer("new " + className + "()").addModifiers(Modifier.FINAL, Modifier.STATIC, Modifier.PUBLIC).build());
write(nullBuilder);
}
@@ -775,9 +793,8 @@ public class EntityProcess extends BaseProcessor{
String baseName(Stype comp){
String suffix = "Comp";
if(!comp.name().endsWith(suffix)) err("All components must have names that end with 'Comp'", comp.e);
boolean isConcrete = comp.has(EntityDef.class); //concrete base implementations have no "Base" suffix
return comp.name().substring(0, comp.name().length() - suffix.length()) + (isConcrete ? "" : "Base");
return comp.name().substring(0, comp.name().length() - suffix.length());
}
@Nullable Stype interfaceToComp(Stype type){

View File

@@ -5,9 +5,7 @@ import com.squareup.javapoet.*;
import mindustry.annotations.*;
import mindustry.annotations.util.TypeIOResolver.*;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.*;
import java.lang.reflect.*;
import java.util.*;
/** Generates code for reading remote invoke packets on the client and server. */
@@ -39,14 +37,8 @@ public class RemoteReadGenerator{
.returns(void.class);
if(needsPlayer){
//since the player type isn't loaded yet, creating a type def is necessary
//this requires reflection since the TypeName constructor is private for some reason
Constructor<TypeName> cons = TypeName.class.getDeclaredConstructor(String.class);
cons.setAccessible(true);
TypeName playerType = cons.newInstance("mindustry.gen.Playerc");
//add player parameter
readMethod.addParameter(playerType, "player");
readMethod.addParameter(ClassName.get(packageName, "Player"), "player");
}
CodeBlock.Builder readBlock = CodeBlock.builder(); //start building block of code inside read method
@@ -111,7 +103,7 @@ public class RemoteReadGenerator{
if(entry.forward && entry.where.isServer && needsPlayer){
//call forwarded method
readBlock.addStatement(packageName + "." + entry.className + "." + entry.element.getSimpleName() +
"__forward(player.con()" + (varResult.length() == 0 ? "" : ", ") + varResult.toString() + ")");
"__forward(player.con" + (varResult.length() == 0 ? "" : ", ") + varResult.toString() + ")");
}
readBlock.nextControlFlow("catch (java.lang.Exception e)");

View File

@@ -81,8 +81,8 @@ public class RemoteWriteGenerator{
return;
}
if(!elem.getParameters().get(0).asType().toString().contains("Playerc")){
BaseProcessor.err("Client invoke methods should have a first parameter of type Playerc", elem);
if(!elem.getParameters().get(0).asType().toString().contains("Player")){
BaseProcessor.err("Client invoke methods should have a first parameter of type Player", elem);
return;
}
}

View File

@@ -17,6 +17,6 @@ public class SerializerResolver{
}
private static boolean isEntity(TypeMirror mirror){
return !mirror.toString().contains(".") && mirror.toString().endsWith("c");
return !mirror.toString().contains(".") || mirror.toString().startsWith("mindustry.gen.") && !mirror.toString().startsWith("byte");
}
}