Fix LinkageProcessor
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful

Dieser Commit ist enthalten in:
yoyosource 2022-09-22 12:19:45 +02:00
Ursprung 1c7e9ad039
Commit 05f5d3f7b3

Datei anzeigen

@ -23,11 +23,13 @@ import de.steamwar.linkage.plan.BuildPlan;
import de.steamwar.linkage.plan.FieldBuilder;
import de.steamwar.linkage.plan.MethodBuilder;
import de.steamwar.linkage.plan.ParameterBuilder;
import de.steamwar.linkage.types.ListenerLink;
import lombok.Getter;
import lombok.SneakyThrows;
import javax.annotation.processing.*;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.*;
import javax.lang.model.type.DeclaredType;
@ -40,17 +42,16 @@ import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@SupportedAnnotationTypes({"de.steamwar.linkage.Linked", "de.steamwar.linkage.Linked$Linkages"})
public class LinkageProcessor extends AbstractProcessor {
@Getter
private static LinkageType.Context context;
private String name;
private String packageName;
private String className;
private Messager messager;
private Writer writer;
private boolean processed = false;
@Override
@ -58,6 +59,13 @@ public class LinkageProcessor extends AbstractProcessor {
return SourceVersion.latestSupported();
}
@Override
public Set<String> getSupportedAnnotationTypes() {
return Stream.of(Linked.class, Linked.Linkages.class)
.map(Class::getCanonicalName)
.collect(Collectors.toSet());
}
@SneakyThrows
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
@ -68,9 +76,9 @@ public class LinkageProcessor extends AbstractProcessor {
name = name.toLowerCase();
context = name.contains("bungee") ? LinkageType.Context.BUNGEE : LinkageType.Context.SPIGOT;
writer = processingEnv.getFiler().createSourceFile("de.steamwar." + name + ".linkage.LinkageUtils").openWriter();
messager = processingEnv.getMessager();
this.name = name;
packageName = "de.steamwar." + name + ".linkage";
className = "LinkageUtils";
}
@ -78,9 +86,11 @@ public class LinkageProcessor extends AbstractProcessor {
@SneakyThrows
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
messager.printMessage(Diagnostic.Kind.NOTE, "Processing linkage types");
if (processed) return false;
processed = true;
Writer writer = processingEnv.getFiler().createSourceFile("de.steamwar." + name + ".linkage.LinkageUtils").openWriter();
BuildPlan buildPlan = new BuildPlan(packageName, className);
buildPlan.addImport("java.util.Set");
buildPlan.addImport("java.lang.Class");
@ -160,64 +170,74 @@ public class LinkageProcessor extends AbstractProcessor {
MinVersion minVersion = element.getAnnotation(MinVersion.class);
System.out.println("Found element: " + typeElement.getQualifiedName().toString());
element.getAnnotationMirrors().forEach(annotationMirror -> {
if (!annotationMirror.getAnnotationType().asElement().getSimpleName().toString().equals("Linked")) return;
Class<?> clazz = annotationMirror.getElementValues().entrySet().stream()
.filter(entry -> entry.getKey().getSimpleName().toString().equals("value"))
.map(Map.Entry::getValue)
.map(AnnotationValue::getValue)
.map(Object::toString)
.map(s -> {
try {
return Class.forName(s);
} catch (ClassNotFoundException e) {
return null;
}
})
.findFirst()
.orElse(null);
if (clazz == null) {
messager.printMessage(Diagnostic.Kind.ERROR, "No class specified", element);
return;
}
element.getAnnotationMirrors().stream()
.filter(annotationMirror -> {
String annotationNames = annotationMirror.getAnnotationType().asElement().getSimpleName().toString();
return annotationNames.equals("Linked") || annotationNames.equals("Linkages");
})
.flatMap(annotationMirror -> annotationMirror.getElementValues().values().stream())
.map(AnnotationValue::getValue)
.flatMap(o -> {
if (o instanceof List) {
return ((List<Object>) o).stream()
.map(AnnotationMirror.class::cast)
.map(AnnotationMirror::getElementValues)
.map(Map::values)
.flatMap(Collection::stream)
.map(AnnotationValue::getValue);
}
return Stream.of(o);
})
.map(Object::toString)
.map(s -> {
try {
return Class.forName(s);
} catch (Exception e) {
messager.printMessage(Diagnostic.Kind.ERROR, "Could not find class " + s, element);
return null;
}
})
.filter(Objects::nonNull)
.map(clazz -> {
try {
return (LinkageType) clazz.getDeclaredConstructor().newInstance();
} catch (Exception e) {
messager.printMessage(Diagnostic.Kind.ERROR, "Could not create instance of " + clazz.getName(), element);
return null;
}
})
.filter(Objects::nonNull)
.forEach(type -> {
Class<? extends LinkageType> clazz = type.getClass();
if (!type.requirements(typeElement.getSuperclass().toString(), typeElement.getInterfaces().stream().map(TypeMirror::toString).collect(Collectors.toSet()))) {
return;
}
LinkageType type = null;
try {
type = (LinkageType) clazz.getDeclaredConstructor().newInstance();
} catch (Exception e) {
messager.printMessage(Diagnostic.Kind.ERROR, "Could not instantiate class", element);
return;
}
if (alreadyGenerated.add(clazz)) {
runMethod.addLine("if (type == " + clazz.getTypeName() + ".class) {");
runMethod.addLine(" run" + clazz.getSimpleName() + "();");
runMethod.addLine("}");
}
if (!type.requirements(typeElement.getSuperclass().toString(), typeElement.getInterfaces().stream().map(TypeMirror::toString).collect(Collectors.toSet()))) {
return;
}
if (alreadyGenerated.add((Class<? extends LinkageType>) clazz)) {
runMethod.addLine("if (type == " + clazz.getTypeName() + ".class) {");
runMethod.addLine(" run" + clazz.getSimpleName() + "();");
runMethod.addLine("}");
}
MethodBuilder method = methods.computeIfAbsent(clazz, t -> {
MethodBuilder methodBuilder = new MethodBuilder("run" + t.getSimpleName(), "void");
methodBuilder.setPrivate(true);
buildPlan.addMethod(methodBuilder);
return methodBuilder;
});
if (context == LinkageType.Context.SPIGOT && minVersion != null) {
method.addLine("if (de.steamwar.core.Core.getVersion() >= " + minVersion.value() + ") {");
}
type.generateCode(buildPlan, method, getElement(typeElement, neededFields), typeElement);
if (context == LinkageType.Context.SPIGOT && minVersion != null) {
method.addLine("}");
}
});
MethodBuilder method = methods.computeIfAbsent(clazz, t -> {
MethodBuilder methodBuilder = new MethodBuilder("run" + t.getSimpleName(), "void");
methodBuilder.setPrivate(true);
buildPlan.addMethod(methodBuilder);
return methodBuilder;
});
if (context == LinkageType.Context.SPIGOT && minVersion != null) {
method.addLine("if (de.steamwar.core.Core.getVersion() >= " + minVersion.value() + ") {");
}
type.generateCode(buildPlan, method, getElement(typeElement, neededFields), typeElement);
if (context == LinkageType.Context.SPIGOT && minVersion != null) {
method.addLine("}");
}
});
}
BufferedWriter writer = new BufferedWriter(this.writer);
buildPlan.write(writer);
writer.close();
BufferedWriter bufferedWriter = new BufferedWriter(writer);
buildPlan.write(bufferedWriter);
bufferedWriter.close();
return true;
}