Dieser Commit ist enthalten in:
Ursprung
1c7e9ad039
Commit
05f5d3f7b3
@ -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;
|
||||
}
|
||||
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren