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