Brute force all markers

This commit is contained in:
Fury_Phoenix 2023-12-10 16:00:05 -08:00
parent f6cba43365
commit 52293cbc50
No known key found for this signature in database
GPG Key ID: 0595F98084987DB8

View File

@ -6,8 +6,10 @@ import java.lang.annotation.Annotation;
import java.lang.invoke.*;
import java.util.Collection;
import java.util.HashSet;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -40,15 +42,10 @@ public class ClientMixinValidator {
private final boolean debug;
private static final Collection<String> markers = Set.of(
"net.fabricmc.api.Environment",
"net.minecraftforge.api.distmarker.OnlyIn",
"net.neoforged.api.distmarker.OnlyIn");
private static final Collection<String> markerEnums = Set.of(
"net.fabricmc.api.EnvType",
"net.minecraftforge.api.distmarker.Dist",
"net.neoforged.api.distmarker.Dist");
private static final Map<String, String> markers = Map.of(
"net.fabricmc.api.Environment", "net.fabricmc.api.EnvType",
"net.minecraftforge.api.distmarker.OnlyIn", "net.minecraftforge.api.distmarker.Dist",
"net.neoforged.api.distmarker.OnlyIn", "net.neoforged.api.distmarker.Dist");
private static final Collection<String> unannotatedClasses = new HashSet<>();
@ -101,20 +98,20 @@ public class ClientMixinValidator {
}
private boolean isClientMarked(TypeElement te) {
Annotation marker = te.getAnnotation(getMarkerClass(markers));
if(marker == null) {
if(debug && unannotatedClasses.add(te.toString())) {
messager.printMessage(Diagnostic.Kind.WARNING,
"Missing " + getMarkerClass(markers).getCanonicalName() + " on " + te + "!");
}
for (var entry : getPlatformClasses(markers).entrySet()) {
Annotation marker = te.getAnnotation(entry.getKey());
if(marker == null) continue;
Optional<MethodHandle> accessor = getAccessor(entry.getKey(), entry.getValue());
Optional<String> enumValue = accessor.map((mh) -> this.invoke(mh, marker))
.map(Object::toString);
if(enumValue.isPresent())
return enumValue.orElseThrow().equals("CLIENT");
return false;
}
try {
Object value = getAccessor().invoke(marker);
return value.toString().equals("CLIENT");
} catch (Throwable e) {
messager.printMessage(Diagnostic.Kind.ERROR, "Fatal error:" +
Throwables.getStackTraceAsString(e));
if(debug && unannotatedClasses.add(te.toString())) {
messager.printMessage(Diagnostic.Kind.WARNING,
"No marker annotations present on " + te + "!");
}
return false;
}
@ -125,11 +122,13 @@ public class ClientMixinValidator {
return false;
}
private MethodHandle getAccessor() throws ReflectiveOperationException {
Class<? extends Annotation> markerClass = getMarkerClass(markers);
Class<? extends Enum<?>> markerEnumClass = getMarkerEnumClass(markerEnums);
MethodType enumValueAccessorType = MethodType.methodType(markerEnumClass);
return lookup.findVirtual(markerClass, "value", enumValueAccessorType);
private static Optional<MethodHandle> getAccessor(Class<? extends Annotation> markerClass,
Class<? extends Enum<?>> enumClass) {
MethodType enumValueAccessorType = MethodType.methodType(enumClass);
try {
return Optional.of(lookup.findVirtual(markerClass, "value", enumValueAccessorType));
} catch (ReflectiveOperationException e) {}
return Optional.empty();
}
public SimpleImmutableEntry<? extends CharSequence, ? extends CharSequence>
@ -155,38 +154,54 @@ public class ClientMixinValidator {
return getTypeHandle(annotatedClass).getAnnotation(annotation);
}
private static List<Object> getTargets(IAnnotationHandle mixinAnnotation) {
private static Collection<Object> getTargets(IAnnotationHandle mixinAnnotation) {
Collection<? extends TypeMirror> clzss = mixinAnnotation.getList("value");
Collection<? extends String> imaginary = mixinAnnotation.getList("targets");
List<Object> targets =
Collection<Object> targets =
Stream.of(clzss, imaginary)
.flatMap(Collection::stream)
.collect(Collectors.toList());
return targets;
}
@SuppressWarnings("unchecked")
private static Class<? extends Annotation> getMarkerClass(Collection<String> markerSet) {
for(var annotation : markerSet) {
try {
return (Class<Annotation>)Class.forName(annotation);
} catch (ClassNotFoundException e) {}
private static Map<Class<? extends Annotation>, Class<? extends Enum<?>>>
getPlatformClasses(Map<String, String> map) {
Map<Class<? extends Annotation>, Class<? extends Enum<?>>> platformClasses = new HashMap<>();
for(var entry : map.entrySet()) {
Optional<Class<? extends Annotation>> annotation = getMarkerClass(entry.getKey());
Optional<Class<? extends Enum<?>>> enumClz = getMarkerEnumClass(entry.getValue());
if(!annotation.isEmpty() && !enumClz.isEmpty())
platformClasses.put(annotation.orElseThrow(), enumClz.orElseThrow());
}
throw new RuntimeException();
return platformClasses;
}
@SuppressWarnings("unchecked")
private static Class<? extends Enum<?>> getMarkerEnumClass(Collection<String> enumSet) {
for(var enumClass : enumSet) {
try {
return (Class<Enum<?>>)Class.forName(enumClass);
} catch (ClassNotFoundException e) {}
}
throw new RuntimeException();
private static Optional<Class<? extends Annotation>> getMarkerClass(String marker) {
try {
return Optional.of((Class<? extends Annotation>)Class.forName(marker));
} catch (ClassNotFoundException e) {}
return Optional.empty();
}
@SuppressWarnings("unchecked")
private static Optional<Class<? extends Enum<?>>> getMarkerEnumClass(String enumClz) {
try {
Optional.of((Class<? extends Enum<?>>)Class.forName(enumClz));
} catch (ClassNotFoundException e) {}
return Optional.empty();
}
public static String toSourceString(String bytecodeName) {
return bytecodeName.replaceAll("\\/", ".");
}
private Object invoke(MethodHandle mh, Annotation marker) {
try { return mh.invoke(marker); }
catch (Throwable e) {
messager.printMessage(Diagnostic.Kind.ERROR, "Fatal error:" +
Throwables.getStackTraceAsString(e));
}
return null;
}
}