diff --git a/src/de/steamwar/linkage/LinkageProcessor.java b/src/de/steamwar/linkage/LinkageProcessor.java index ee18e5a..3a7c3d2 100644 --- a/src/de/steamwar/linkage/LinkageProcessor.java +++ b/src/de/steamwar/linkage/LinkageProcessor.java @@ -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 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 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) 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 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) 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; }