From 860d0827703f634c8dfcb1c43ec93b544c37d25b Mon Sep 17 00:00:00 2001 From: yoyosource Date: Mon, 26 Sep 2022 15:58:06 +0200 Subject: [PATCH 1/3] Simplify LinkageProcessor --- src/de/steamwar/linkage/LinkageProcessor.java | 40 +++++++++---------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/src/de/steamwar/linkage/LinkageProcessor.java b/src/de/steamwar/linkage/LinkageProcessor.java index 5e34d44..70253df 100644 --- a/src/de/steamwar/linkage/LinkageProcessor.java +++ b/src/de/steamwar/linkage/LinkageProcessor.java @@ -28,7 +28,10 @@ import lombok.SneakyThrows; import javax.annotation.processing.*; import javax.lang.model.SourceVersion; -import javax.lang.model.element.*; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeMirror; import javax.tools.Diagnostic; @@ -116,25 +119,23 @@ public class LinkageProcessor extends AbstractProcessor { BuildPlan buildPlan = new BuildPlan(packageName, className); - Set elements = roundEnv.getElementsAnnotatedWith(Linked.class); + Set elements = roundEnv.getElementsAnnotatedWith(Linked.class).stream() + .filter(element -> element.getKind() == ElementKind.CLASS) + .map(TypeElement.class::cast) + .collect(Collectors.toSet()); + Map neededFields = new HashMap<>(); Set fieldInjections = new HashSet<>(); - for (Element element : elements) { - if (element.getKind() != ElementKind.CLASS) { - continue; - } - TypeElement typeElement = (TypeElement) element; - Linked linked = element.getAnnotation(Linked.class); - if (linked == null) { - continue; - } + for (TypeElement typeElement : elements) { if (getLinkagesOfType(typeElement).size() > 1) { neededFields.put(typeElement.getQualifiedName().toString(), typeElement); } - List variableElements = typeElement.getEnclosedElements().stream().filter(e -> e.getKind() == ElementKind.FIELD).map(VariableElement.class::cast).filter(e -> { - return e.getAnnotation(LinkedInstance.class) != null; - }).collect(Collectors.toList()); + List variableElements = typeElement.getEnclosedElements().stream() + .filter(e -> e.getKind() == ElementKind.FIELD) + .map(VariableElement.class::cast) + .filter(e -> e.getAnnotation(LinkedInstance.class) != null) + .collect(Collectors.toList()); if (variableElements.isEmpty()) { continue; } @@ -177,12 +178,7 @@ public class LinkageProcessor extends AbstractProcessor { fieldInjections.forEach(Runnable::run); Map methods = new HashMap<>(); - for (Element element : elements) { - if (element.getKind() != ElementKind.CLASS) { - continue; - } - TypeElement typeElement = (TypeElement) element; - + for (TypeElement typeElement : elements) { System.out.println("Found element: " + typeElement.getQualifiedName().toString()); Map> linkages = getLinkagesOfType(typeElement); if (linkages.isEmpty()) { @@ -211,11 +207,11 @@ public class LinkageProcessor extends AbstractProcessor { } private String getElement(TypeElement typeElement, Map neededFields) { + String s = typeElement.getSimpleName().toString(); if (neededFields.containsKey(typeElement.getQualifiedName().toString())) { - String s = typeElement.getSimpleName().toString(); return s.substring(0, 1).toLowerCase() + s.substring(1); } - return "new " + typeElement.getSimpleName().toString() + "()"; + return "new " + s + "()"; } private void specialElements(TypeElement typeElement, BuildPlan buildPlan, Consumer stringConsumer, Runnable inner) { From 30299be974f9bc31097987020293fc432c661ae6 Mon Sep 17 00:00:00 2001 From: yoyosource Date: Mon, 26 Sep 2022 16:40:42 +0200 Subject: [PATCH 2/3] Optimize some more stuff --- src/de/steamwar/linkage/LinkageProcessor.java | 99 +++++++++---------- 1 file changed, 48 insertions(+), 51 deletions(-) diff --git a/src/de/steamwar/linkage/LinkageProcessor.java b/src/de/steamwar/linkage/LinkageProcessor.java index 70253df..7965140 100644 --- a/src/de/steamwar/linkage/LinkageProcessor.java +++ b/src/de/steamwar/linkage/LinkageProcessor.java @@ -23,6 +23,7 @@ import de.steamwar.linkage.plan.BuildPlan; import de.steamwar.linkage.plan.FieldBuilder; import de.steamwar.linkage.plan.MethodBuilder; import de.steamwar.linkage.types.Plain_GENERIC; +import lombok.Cleanup; import lombok.Getter; import lombok.SneakyThrows; @@ -42,6 +43,7 @@ import java.nio.file.Path; import java.util.*; import java.util.function.Consumer; import java.util.stream.Collectors; +import java.util.stream.Stream; @SupportedAnnotationTypes("de.steamwar.linkage.Linked") public class LinkageProcessor extends AbstractProcessor { @@ -52,7 +54,6 @@ public class LinkageProcessor extends AbstractProcessor { private static String pluginMain; private String name; - private String packageName; private String className; private Messager messager; @@ -72,7 +73,6 @@ public class LinkageProcessor extends AbstractProcessor { messager = processingEnv.getMessager(); - packageName = "de.steamwar." + name + ".linkage"; className = "LinkageUtils"; mainClass(); } @@ -90,22 +90,15 @@ public class LinkageProcessor extends AbstractProcessor { return; } context = pluginYMLFile.get().getName().equals("bungee.yml") ? Context.BUNGEE : Context.SPIGOT; - Optional mainName = getMainName(pluginYMLFile.get()); - if (!mainName.isPresent()) { + @Cleanup BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(pluginYMLFile.get()))); + Optional mainName = reader.lines() + .filter(line -> line.startsWith("main:")) + .map(line -> line.substring(line.indexOf(':') + 1).trim()) + .findFirst(); + if (mainName.isPresent()) { + pluginMain = mainName.get(); + } else { messager.printMessage(Diagnostic.Kind.ERROR, "Could not find main class in plugin.yml or bungee.yml"); - return; - } - pluginMain = mainName.get(); - } - - @SneakyThrows - private Optional getMainName(File pluginYML) { - if (!pluginYML.exists()) return Optional.empty(); - try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(pluginYML)))) { - return reader.lines() - .filter(line -> line.startsWith("main:")) - .map(line -> line.substring(line.indexOf(':') + 1).trim()) - .findFirst(); } } @@ -116,14 +109,17 @@ public class LinkageProcessor extends AbstractProcessor { processed = true; Writer writer = processingEnv.getFiler().createSourceFile("de.steamwar." + name + ".linkage.LinkageUtils").openWriter(); - - BuildPlan buildPlan = new BuildPlan(packageName, className); + BuildPlan buildPlan = new BuildPlan("de.steamwar." + name + ".linkage", className); Set elements = roundEnv.getElementsAnnotatedWith(Linked.class).stream() .filter(element -> element.getKind() == ElementKind.CLASS) .map(TypeElement.class::cast) + .peek(typeElement -> System.out.println("Found element: " + typeElement.getQualifiedName().toString())) .collect(Collectors.toSet()); + Map, List> groupedByChecks = elements.stream() + .collect(Collectors.groupingBy(element -> checks(element, buildPlan))); + Map neededFields = new HashMap<>(); Set fieldInjections = new HashSet<>(); for (TypeElement typeElement : elements) { @@ -136,9 +132,7 @@ public class LinkageProcessor extends AbstractProcessor { .map(VariableElement.class::cast) .filter(e -> e.getAnnotation(LinkedInstance.class) != null) .collect(Collectors.toList()); - if (variableElements.isEmpty()) { - continue; - } + if (variableElements.isEmpty()) continue; for (VariableElement variableElement : variableElements) { if (!variableElement.getModifiers().contains(Modifier.PUBLIC)) { @@ -178,25 +172,33 @@ public class LinkageProcessor extends AbstractProcessor { fieldInjections.forEach(Runnable::run); Map methods = new HashMap<>(); - for (TypeElement typeElement : elements) { - System.out.println("Found element: " + typeElement.getQualifiedName().toString()); - Map> linkages = getLinkagesOfType(typeElement); - if (linkages.isEmpty()) { - continue; + for (Map.Entry, List> entry : groupedByChecks.entrySet()) { + Map>> groupedByMethod = new HashMap<>(); + for (TypeElement typeElement : entry.getValue()) { + for (Map.Entry> linkages : getLinkagesOfType(typeElement).entrySet()) { + Map> internalGroup = groupedByMethod.computeIfAbsent(linkages.getKey(), s -> new HashMap<>()); + for (LinkageType linkageType : linkages.getValue()) { + List list = internalGroup.computeIfAbsent(linkageType, s -> new ArrayList<>()); + list.add(typeElement); + } + } } - for (Map.Entry> entry : linkages.entrySet()) { - MethodBuilder method = methods.computeIfAbsent(entry.getKey(), s -> { + for (Map.Entry>> group : groupedByMethod.entrySet()) { + MethodBuilder method = methods.computeIfAbsent(group.getKey(), s -> { MethodBuilder methodBuilder = new MethodBuilder(s, "void"); buildPlan.addMethod(methodBuilder); return methodBuilder; }); - for (LinkageType type : entry.getValue()) { - specialElements(typeElement, buildPlan, method::addLine, () -> { + + if (!entry.getKey().isEmpty()) method.addLine("if (" + String.join(" && ", entry.getKey()) + ") {"); + for (Map.Entry> toGenerate : group.getValue().entrySet()) { + toGenerate.getValue().forEach(typeElement -> { buildPlan.addImport(typeElement.getQualifiedName().toString()); - type.generateCode(buildPlan, method, getElement(typeElement, neededFields), typeElement); + toGenerate.getKey().generateCode(buildPlan, method, getElement(typeElement, neededFields), typeElement); }); } + if (!entry.getKey().isEmpty()) method.addLine("}"); } } @@ -214,14 +216,14 @@ public class LinkageProcessor extends AbstractProcessor { return "new " + s + "()"; } - private void specialElements(TypeElement typeElement, BuildPlan buildPlan, Consumer stringConsumer, Runnable inner) { + private Set checks(TypeElement typeElement, BuildPlan buildPlan) { + Set checks = new HashSet<>(); MinVersion minVersion = typeElement.getAnnotation(MinVersion.class); MaxVersion maxVersion = typeElement.getAnnotation(MaxVersion.class); EventMode eventMode = typeElement.getAnnotation(EventMode.class); PluginCheck[] pluginChecks = typeElement.getAnnotationsByType(PluginCheck.class); if (context == Context.SPIGOT) { errorOnNonNull(typeElement, eventMode); - List checks = new ArrayList<>(); if (minVersion != null) { buildPlan.addImport("de.steamwar.core.Core"); checks.add("Core.getVersion() >= " + minVersion.value()); @@ -236,12 +238,8 @@ public class LinkageProcessor extends AbstractProcessor { return "Bukkit.getPluginManager().getPlugin(\"" + pluginCheck.value() + "\") " + (pluginCheck.has() == PluginCheck.Has.THIS ? "!" : "=") + "= null"; }).forEach(checks::add); } - if (!checks.isEmpty()) stringConsumer.accept("if (" + String.join(" && ", checks) + ") {"); - inner.run(); - if (!checks.isEmpty()) stringConsumer.accept("}"); } else { errorOnNonNull(typeElement, minVersion, maxVersion); - List checks = new ArrayList<>(); if (eventMode != null) { buildPlan.addImport("de.steamwar.bungeecore.BungeeCore"); checks.add(eventMode.value().getPrefix() + "BungeeCore.EVENT_MODE"); @@ -252,10 +250,15 @@ public class LinkageProcessor extends AbstractProcessor { return "BungeeCord.getPluginManager().getPlugin(\"" + pluginCheck.value() + "\") " + (pluginCheck.has() == PluginCheck.Has.THIS ? "!" : "=") + "= null"; }).forEach(checks::add); } - if (!checks.isEmpty()) stringConsumer.accept("if (" + String.join(" && ", checks) + ") {"); - inner.run(); - if (!checks.isEmpty()) stringConsumer.accept("}"); } + return checks; + } + + private void specialElements(TypeElement typeElement, BuildPlan buildPlan, Consumer stringConsumer, Runnable inner) { + Set checks = checks(typeElement, buildPlan); + if (!checks.isEmpty()) stringConsumer.accept("if (" + String.join(" && ", checks) + ") {"); + inner.run(); + if (!checks.isEmpty()) stringConsumer.accept("}"); } private void errorOnNonNull(TypeElement typeElement, Annotation... annotations) { @@ -270,16 +273,10 @@ public class LinkageProcessor extends AbstractProcessor { private Map> getLinkagesOfType(TypeElement typeElement) { Map> linkages = new HashMap<>(); - LinkageType superClassType = resolveSingle(typeElement.getSuperclass()); - if (superClassType != null) { - linkages.computeIfAbsent(superClassType.method(), s -> new ArrayList<>()).add(superClassType); - } - for (TypeMirror typeMirror : typeElement.getInterfaces()) { - LinkageType interfaceType = resolveSingle(typeMirror); - if (interfaceType != null) { - linkages.computeIfAbsent(interfaceType.method(), s -> new ArrayList<>()).add(interfaceType); - } - } + Stream.concat(Stream.of(typeElement.getSuperclass()), typeElement.getInterfaces().stream()) + .map(this::resolveSingle) + .filter(Objects::nonNull) + .forEach(linkageType -> linkages.computeIfAbsent(linkageType.method(), s -> new ArrayList<>()).add(linkageType)); if (linkages.size() == 1 && linkages.containsKey("unlink")) { linkages.put(plain_GENERIC.method(), Collections.singletonList(plain_GENERIC)); } From 4f4caac67f26f68370ab3f4b07f9e199d1ec99c2 Mon Sep 17 00:00:00 2001 From: yoyosource Date: Sat, 25 Feb 2023 15:04:30 +0100 Subject: [PATCH 3/3] Fix LinkageProcessor --- src/de/steamwar/linkage/LinkageProcessor.java | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/de/steamwar/linkage/LinkageProcessor.java b/src/de/steamwar/linkage/LinkageProcessor.java index f547817..488f9bf 100644 --- a/src/de/steamwar/linkage/LinkageProcessor.java +++ b/src/de/steamwar/linkage/LinkageProcessor.java @@ -173,18 +173,15 @@ public class LinkageProcessor extends AbstractProcessor { Map methods = new HashMap<>(); for (Map.Entry, List> entry : groupedByChecks.entrySet()) { - Map>> groupedByMethod = new HashMap<>(); + Map>> groupedByMethod = new HashMap<>(); for (TypeElement typeElement : entry.getValue()) { for (Map.Entry> linkages : getLinkagesOfType(typeElement).entrySet()) { - Map> internalGroup = groupedByMethod.computeIfAbsent(linkages.getKey(), s -> new HashMap<>()); - for (LinkageType linkageType : linkages.getValue()) { - List list = internalGroup.computeIfAbsent(linkageType, s -> new ArrayList<>()); - list.add(typeElement); - } + groupedByMethod.computeIfAbsent(linkages.getKey(), ignored -> new HashMap<>()) + .put(typeElement, linkages.getValue()); } } - for (Map.Entry>> group : groupedByMethod.entrySet()) { + for (Map.Entry>> group : groupedByMethod.entrySet()) { MethodBuilder method = methods.computeIfAbsent(group.getKey(), s -> { MethodBuilder methodBuilder = new MethodBuilder(s, "void"); buildPlan.addMethod(methodBuilder); @@ -192,10 +189,17 @@ public class LinkageProcessor extends AbstractProcessor { }); if (!entry.getKey().isEmpty()) method.addLine("if (" + String.join(" && ", entry.getKey()) + ") {"); - for (Map.Entry> toGenerate : group.getValue().entrySet()) { - toGenerate.getValue().forEach(typeElement -> { + for (Map.Entry> toGenerate : group.getValue().entrySet()) { + TypeElement typeElement = toGenerate.getKey(); + String instance = getElement(typeElement, neededFields); + if (toGenerate.getValue().size() > 1 && instance.startsWith("new ")) { + method.addLine(typeElement.getSimpleName() + " local" + typeElement.getSimpleName().toString() + " = " + instance + ";"); + instance = "local" + typeElement.getSimpleName().toString(); + } + String finalInstance = instance; + toGenerate.getValue().forEach(linkageType -> { buildPlan.addImport(typeElement.getQualifiedName().toString()); - toGenerate.getKey().generateCode(buildPlan, method, getElement(typeElement, neededFields), typeElement); + linkageType.generateCode(buildPlan, method, finalInstance, typeElement); }); } if (!entry.getKey().isEmpty()) method.addLine("}");