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