Optimize some more stuff
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful

Dieser Commit ist enthalten in:
yoyosource 2022-09-26 16:40:42 +02:00
Ursprung 860d082770
Commit 30299be974

Datei anzeigen

@ -23,6 +23,7 @@ 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.types.Plain_GENERIC; import de.steamwar.linkage.types.Plain_GENERIC;
import lombok.Cleanup;
import lombok.Getter; import lombok.Getter;
import lombok.SneakyThrows; import lombok.SneakyThrows;
@ -42,6 +43,7 @@ import java.nio.file.Path;
import java.util.*; import java.util.*;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
@SupportedAnnotationTypes("de.steamwar.linkage.Linked") @SupportedAnnotationTypes("de.steamwar.linkage.Linked")
public class LinkageProcessor extends AbstractProcessor { public class LinkageProcessor extends AbstractProcessor {
@ -52,7 +54,6 @@ public class LinkageProcessor extends AbstractProcessor {
private static String pluginMain; private static String pluginMain;
private String name; private String name;
private String packageName;
private String className; private String className;
private Messager messager; private Messager messager;
@ -72,7 +73,6 @@ public class LinkageProcessor extends AbstractProcessor {
messager = processingEnv.getMessager(); messager = processingEnv.getMessager();
packageName = "de.steamwar." + name + ".linkage";
className = "LinkageUtils"; className = "LinkageUtils";
mainClass(); mainClass();
} }
@ -90,22 +90,15 @@ public class LinkageProcessor extends AbstractProcessor {
return; return;
} }
context = pluginYMLFile.get().getName().equals("bungee.yml") ? Context.BUNGEE : Context.SPIGOT; context = pluginYMLFile.get().getName().equals("bungee.yml") ? Context.BUNGEE : Context.SPIGOT;
Optional<String> mainName = getMainName(pluginYMLFile.get()); @Cleanup BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(pluginYMLFile.get())));
if (!mainName.isPresent()) { Optional<String> mainName = reader.lines()
messager.printMessage(Diagnostic.Kind.ERROR, "Could not find main class in plugin.yml or bungee.yml");
return;
}
pluginMain = mainName.get();
}
@SneakyThrows
private Optional<String> 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:")) .filter(line -> line.startsWith("main:"))
.map(line -> line.substring(line.indexOf(':') + 1).trim()) .map(line -> line.substring(line.indexOf(':') + 1).trim())
.findFirst(); .findFirst();
if (mainName.isPresent()) {
pluginMain = mainName.get();
} else {
messager.printMessage(Diagnostic.Kind.ERROR, "Could not find main class in plugin.yml or bungee.yml");
} }
} }
@ -116,14 +109,17 @@ public class LinkageProcessor extends AbstractProcessor {
processed = true; processed = true;
Writer writer = processingEnv.getFiler().createSourceFile("de.steamwar." + name + ".linkage.LinkageUtils").openWriter(); Writer writer = processingEnv.getFiler().createSourceFile("de.steamwar." + name + ".linkage.LinkageUtils").openWriter();
BuildPlan buildPlan = new BuildPlan("de.steamwar." + name + ".linkage", className);
BuildPlan buildPlan = new BuildPlan(packageName, className);
Set<TypeElement> elements = roundEnv.getElementsAnnotatedWith(Linked.class).stream() Set<TypeElement> elements = roundEnv.getElementsAnnotatedWith(Linked.class).stream()
.filter(element -> element.getKind() == ElementKind.CLASS) .filter(element -> element.getKind() == ElementKind.CLASS)
.map(TypeElement.class::cast) .map(TypeElement.class::cast)
.peek(typeElement -> System.out.println("Found element: " + typeElement.getQualifiedName().toString()))
.collect(Collectors.toSet()); .collect(Collectors.toSet());
Map<Set<String>, List<TypeElement>> groupedByChecks = elements.stream()
.collect(Collectors.groupingBy(element -> checks(element, buildPlan)));
Map<String, TypeElement> neededFields = new HashMap<>(); Map<String, TypeElement> neededFields = new HashMap<>();
Set<Runnable> fieldInjections = new HashSet<>(); Set<Runnable> fieldInjections = new HashSet<>();
for (TypeElement typeElement : elements) { for (TypeElement typeElement : elements) {
@ -136,9 +132,7 @@ public class LinkageProcessor extends AbstractProcessor {
.map(VariableElement.class::cast) .map(VariableElement.class::cast)
.filter(e -> e.getAnnotation(LinkedInstance.class) != null) .filter(e -> e.getAnnotation(LinkedInstance.class) != null)
.collect(Collectors.toList()); .collect(Collectors.toList());
if (variableElements.isEmpty()) { if (variableElements.isEmpty()) continue;
continue;
}
for (VariableElement variableElement : variableElements) { for (VariableElement variableElement : variableElements) {
if (!variableElement.getModifiers().contains(Modifier.PUBLIC)) { if (!variableElement.getModifiers().contains(Modifier.PUBLIC)) {
@ -178,25 +172,33 @@ public class LinkageProcessor extends AbstractProcessor {
fieldInjections.forEach(Runnable::run); fieldInjections.forEach(Runnable::run);
Map<String, MethodBuilder> methods = new HashMap<>(); Map<String, MethodBuilder> methods = new HashMap<>();
for (TypeElement typeElement : elements) { for (Map.Entry<Set<String>, List<TypeElement>> entry : groupedByChecks.entrySet()) {
System.out.println("Found element: " + typeElement.getQualifiedName().toString()); Map<String, Map<LinkageType, List<TypeElement>>> groupedByMethod = new HashMap<>();
Map<String, List<LinkageType>> linkages = getLinkagesOfType(typeElement); for (TypeElement typeElement : entry.getValue()) {
if (linkages.isEmpty()) { for (Map.Entry<String, List<LinkageType>> linkages : getLinkagesOfType(typeElement).entrySet()) {
continue; Map<LinkageType, List<TypeElement>> internalGroup = groupedByMethod.computeIfAbsent(linkages.getKey(), s -> new HashMap<>());
for (LinkageType linkageType : linkages.getValue()) {
List<TypeElement> list = internalGroup.computeIfAbsent(linkageType, s -> new ArrayList<>());
list.add(typeElement);
}
}
} }
for (Map.Entry<String, List<LinkageType>> entry : linkages.entrySet()) { for (Map.Entry<String, Map<LinkageType, List<TypeElement>>> group : groupedByMethod.entrySet()) {
MethodBuilder method = methods.computeIfAbsent(entry.getKey(), s -> { MethodBuilder method = methods.computeIfAbsent(group.getKey(), s -> {
MethodBuilder methodBuilder = new MethodBuilder(s, "void"); MethodBuilder methodBuilder = new MethodBuilder(s, "void");
buildPlan.addMethod(methodBuilder); buildPlan.addMethod(methodBuilder);
return 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<LinkageType, List<TypeElement>> toGenerate : group.getValue().entrySet()) {
toGenerate.getValue().forEach(typeElement -> {
buildPlan.addImport(typeElement.getQualifiedName().toString()); 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 + "()"; return "new " + s + "()";
} }
private void specialElements(TypeElement typeElement, BuildPlan buildPlan, Consumer<String> stringConsumer, Runnable inner) { private Set<String> checks(TypeElement typeElement, BuildPlan buildPlan) {
Set<String> checks = new HashSet<>();
MinVersion minVersion = typeElement.getAnnotation(MinVersion.class); MinVersion minVersion = typeElement.getAnnotation(MinVersion.class);
MaxVersion maxVersion = typeElement.getAnnotation(MaxVersion.class); MaxVersion maxVersion = typeElement.getAnnotation(MaxVersion.class);
EventMode eventMode = typeElement.getAnnotation(EventMode.class); EventMode eventMode = typeElement.getAnnotation(EventMode.class);
PluginCheck[] pluginChecks = typeElement.getAnnotationsByType(PluginCheck.class); PluginCheck[] pluginChecks = typeElement.getAnnotationsByType(PluginCheck.class);
if (context == Context.SPIGOT) { if (context == Context.SPIGOT) {
errorOnNonNull(typeElement, eventMode); errorOnNonNull(typeElement, eventMode);
List<String> checks = new ArrayList<>();
if (minVersion != null) { if (minVersion != null) {
buildPlan.addImport("de.steamwar.core.Core"); buildPlan.addImport("de.steamwar.core.Core");
checks.add("Core.getVersion() >= " + minVersion.value()); 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"; return "Bukkit.getPluginManager().getPlugin(\"" + pluginCheck.value() + "\") " + (pluginCheck.has() == PluginCheck.Has.THIS ? "!" : "=") + "= null";
}).forEach(checks::add); }).forEach(checks::add);
} }
if (!checks.isEmpty()) stringConsumer.accept("if (" + String.join(" && ", checks) + ") {");
inner.run();
if (!checks.isEmpty()) stringConsumer.accept("}");
} else { } else {
errorOnNonNull(typeElement, minVersion, maxVersion); errorOnNonNull(typeElement, minVersion, maxVersion);
List<String> checks = new ArrayList<>();
if (eventMode != null) { if (eventMode != null) {
buildPlan.addImport("de.steamwar.bungeecore.BungeeCore"); buildPlan.addImport("de.steamwar.bungeecore.BungeeCore");
checks.add(eventMode.value().getPrefix() + "BungeeCore.EVENT_MODE"); checks.add(eventMode.value().getPrefix() + "BungeeCore.EVENT_MODE");
@ -252,11 +250,16 @@ public class LinkageProcessor extends AbstractProcessor {
return "BungeeCord.getPluginManager().getPlugin(\"" + pluginCheck.value() + "\") " + (pluginCheck.has() == PluginCheck.Has.THIS ? "!" : "=") + "= null"; return "BungeeCord.getPluginManager().getPlugin(\"" + pluginCheck.value() + "\") " + (pluginCheck.has() == PluginCheck.Has.THIS ? "!" : "=") + "= null";
}).forEach(checks::add); }).forEach(checks::add);
} }
}
return checks;
}
private void specialElements(TypeElement typeElement, BuildPlan buildPlan, Consumer<String> stringConsumer, Runnable inner) {
Set<String> checks = checks(typeElement, buildPlan);
if (!checks.isEmpty()) stringConsumer.accept("if (" + String.join(" && ", checks) + ") {"); if (!checks.isEmpty()) stringConsumer.accept("if (" + String.join(" && ", checks) + ") {");
inner.run(); inner.run();
if (!checks.isEmpty()) stringConsumer.accept("}"); if (!checks.isEmpty()) stringConsumer.accept("}");
} }
}
private void errorOnNonNull(TypeElement typeElement, Annotation... annotations) { private void errorOnNonNull(TypeElement typeElement, Annotation... annotations) {
for (Annotation annotation : annotations) { for (Annotation annotation : annotations) {
@ -270,16 +273,10 @@ public class LinkageProcessor extends AbstractProcessor {
private Map<String, List<LinkageType>> getLinkagesOfType(TypeElement typeElement) { private Map<String, List<LinkageType>> getLinkagesOfType(TypeElement typeElement) {
Map<String, List<LinkageType>> linkages = new HashMap<>(); Map<String, List<LinkageType>> linkages = new HashMap<>();
LinkageType superClassType = resolveSingle(typeElement.getSuperclass()); Stream.concat(Stream.of(typeElement.getSuperclass()), typeElement.getInterfaces().stream())
if (superClassType != null) { .map(this::resolveSingle)
linkages.computeIfAbsent(superClassType.method(), s -> new ArrayList<>()).add(superClassType); .filter(Objects::nonNull)
} .forEach(linkageType -> linkages.computeIfAbsent(linkageType.method(), s -> new ArrayList<>()).add(linkageType));
for (TypeMirror typeMirror : typeElement.getInterfaces()) {
LinkageType interfaceType = resolveSingle(typeMirror);
if (interfaceType != null) {
linkages.computeIfAbsent(interfaceType.method(), s -> new ArrayList<>()).add(interfaceType);
}
}
if (linkages.size() == 1 && linkages.containsKey("unlink")) { if (linkages.size() == 1 && linkages.containsKey("unlink")) {
linkages.put(plain_GENERIC.method(), Collections.singletonList(plain_GENERIC)); linkages.put(plain_GENERIC.method(), Collections.singletonList(plain_GENERIC));
} }