Improve debug output, update javapoet (#32)

* Update gradle

* Fix test eclipse java compiler compatbility

* Always dump class name on errors, remove some streams, reformat

* Bump javapoet

* Update javapoet
This commit is contained in:
Player 2024-05-15 13:40:29 -04:00 committed by GitHub
parent 8b0f70e572
commit 7efbd4534e
2 changed files with 74 additions and 50 deletions

View File

@ -15,16 +15,17 @@
*/ */
package net.fabricmc.mappingpoet; package net.fabricmc.mappingpoet;
import static net.fabricmc.mappingpoet.FieldBuilder.parseAnnotation;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import com.squareup.javapoet.AnnotationSpec; import com.squareup.javapoet.AnnotationSpec;
import com.squareup.javapoet.ClassName; import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.ParameterSpec; import com.squareup.javapoet.ParameterSpec;
import com.squareup.javapoet.TypeSpec; import com.squareup.javapoet.TypeSpec;
import com.squareup.javapoet.TypeVariableName; import com.squareup.javapoet.TypeVariableName;
import net.fabricmc.mappingpoet.signature.AnnotationAwareDescriptors;
import net.fabricmc.mappingpoet.signature.AnnotationAwareSignatures;
import net.fabricmc.mappingpoet.signature.ClassSignature;
import net.fabricmc.mappingpoet.signature.TypeAnnotationMapping;
import net.fabricmc.mappingpoet.signature.TypeAnnotationStorage;
import org.objectweb.asm.Handle; import org.objectweb.asm.Handle;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import org.objectweb.asm.TypeReference; import org.objectweb.asm.TypeReference;
@ -36,11 +37,11 @@ import org.objectweb.asm.tree.InnerClassNode;
import org.objectweb.asm.tree.InvokeDynamicInsnNode; import org.objectweb.asm.tree.InvokeDynamicInsnNode;
import org.objectweb.asm.tree.MethodNode; import org.objectweb.asm.tree.MethodNode;
import java.lang.reflect.Modifier; import net.fabricmc.mappingpoet.signature.AnnotationAwareDescriptors;
import java.util.ArrayList; import net.fabricmc.mappingpoet.signature.AnnotationAwareSignatures;
import java.util.List; import net.fabricmc.mappingpoet.signature.ClassSignature;
import net.fabricmc.mappingpoet.signature.TypeAnnotationMapping;
import static net.fabricmc.mappingpoet.FieldBuilder.parseAnnotation; import net.fabricmc.mappingpoet.signature.TypeAnnotationStorage;
public class ClassBuilder { public class ClassBuilder {
static final Handle OBJ_MTH_BOOTSTRAP = new Handle( static final Handle OBJ_MTH_BOOTSTRAP = new Handle(
@ -48,8 +49,7 @@ public class ClassBuilder {
"java/lang/runtime/ObjectMethods", "java/lang/runtime/ObjectMethods",
"bootstrap", "bootstrap",
"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/TypeDescriptor;Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object;", "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/TypeDescriptor;Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object;",
false false);
);
private final MappingsStore mappings; private final MappingsStore mappings;
private final ClassNode classNode; private final ClassNode classNode;
@ -131,14 +131,17 @@ public class ClassBuilder {
} }
private ClassSignature setupSignature() { private ClassSignature setupSignature() {
return classNode.signature == null ? if (classNode.signature == null) {
AnnotationAwareDescriptors.parse(classNode.superName, classNode.interfaces, typeAnnotations, environment) : return AnnotationAwareDescriptors.parse(classNode.superName, classNode.interfaces, typeAnnotations, environment);
AnnotationAwareSignatures.parseClassSignature(classNode.signature, typeAnnotations, environment); } else {
return AnnotationAwareSignatures.parseClassSignature(classNode.signature, typeAnnotations, environment);
}
} }
private TypeSpec.Builder setupBuilder() { private TypeSpec.Builder setupBuilder() {
TypeSpec.Builder builder; TypeSpec.Builder builder;
ClassName name = parseInternalName(classNode.name); // no type anno here ClassName name = parseInternalName(classNode.name); // no type anno here
if (Modifier.isInterface(classNode.access)) { if (Modifier.isInterface(classNode.access)) {
if (classNode.interfaces.size() == 1 && classNode.interfaces.get(0).equals("java/lang/annotation/Annotation")) { if (classNode.interfaces.size() == 1 && classNode.interfaces.get(0).equals("java/lang/annotation/Annotation")) {
builder = TypeSpec.annotationBuilder(name); builder = TypeSpec.annotationBuilder(name);
@ -172,18 +175,19 @@ public class ClassBuilder {
return builder return builder
.addModifiers(new ModifierBuilder(classNode.access) .addModifiers(new ModifierBuilder(classNode.access)
.checkUnseal(classNode, environment) .checkUnseal(classNode, environment)
.getModifiers(ModifierBuilder.getType(enumClass, recordClass)) .getModifiers(ModifierBuilder.getType(enumClass, recordClass)));
);
} }
private void addInterfaces() { private void addInterfaces() {
if (annotationClass) { if (annotationClass) {
return; return;
} }
if (signature != null) { if (signature != null) {
builder.addSuperinterfaces(signature.superinterfaces()); builder.addSuperinterfaces(signature.superinterfaces());
return; return;
} }
if (classNode.interfaces.isEmpty()) return; if (classNode.interfaces.isEmpty()) return;
for (String iFace : classNode.interfaces) { for (String iFace : classNode.interfaces) {
@ -201,6 +205,7 @@ public class ClassBuilder {
if (regularAnnotations == null) { if (regularAnnotations == null) {
return; return;
} }
for (AnnotationNode annotation : regularAnnotations) { for (AnnotationNode annotation : regularAnnotations) {
builder.addAnnotation(parseAnnotation(annotation)); builder.addAnnotation(parseAnnotation(annotation));
} }
@ -208,27 +213,33 @@ public class ClassBuilder {
private void addMethods() { private void addMethods() {
if (classNode.methods == null) return; if (classNode.methods == null) return;
methodsLoop:
for (MethodNode method : classNode.methods) { methodsLoop: for (MethodNode method : classNode.methods) {
if ((method.access & Opcodes.ACC_SYNTHETIC) != 0 || (method.access & Opcodes.ACC_MANDATED) != 0) { if ((method.access & Opcodes.ACC_SYNTHETIC) != 0 || (method.access & Opcodes.ACC_MANDATED) != 0) {
continue; continue;
} }
if (method.name.equals("<clinit>")) { if (method.name.equals("<clinit>")) {
continue; continue;
} }
int formalParamStartIndex = 0; int formalParamStartIndex = 0;
if (enumClass) { if (enumClass) {
// Skip enum sugar methods // Skip enum sugar methods
if (method.name.equals("values") && method.desc.equals("()[L" + classNode.name + ";")) { if (method.name.equals("values") && method.desc.equals("()[L" + classNode.name + ";")) {
continue; continue;
} }
if (method.name.equals("valueOf") && method.desc.equals("(Ljava/lang/String;)L" + classNode.name + ";")) { if (method.name.equals("valueOf") && method.desc.equals("(Ljava/lang/String;)L" + classNode.name + ";")) {
continue; continue;
} }
if (method.name.equals("<init>")) { if (method.name.equals("<init>")) {
formalParamStartIndex = 2; // 0 String 1 int formalParamStartIndex = 2; // 0 String 1 int
} }
} }
if (recordClass) { if (recordClass) {
// skip record sugars // skip record sugars
if (method.name.equals("equals") && method.desc.equals("(Ljava/lang/Object;)Z") if (method.name.equals("equals") && method.desc.equals("(Ljava/lang/Object;)Z")
@ -244,17 +255,20 @@ public class ClassBuilder {
// todo test component getters // todo test component getters
} }
if (instanceInner) { if (instanceInner) {
if (method.name.equals("<init>")) { if (method.name.equals("<init>")) {
formalParamStartIndex = 1; // 0 this$0 formalParamStartIndex = 1; // 0 this$0
} }
} }
builder.addMethod(new MethodBuilder(mappings, classNode, method, environment, receiverSignature, formalParamStartIndex).build()); builder.addMethod(new MethodBuilder(mappings, classNode, method, environment, receiverSignature, formalParamStartIndex).build());
} }
} }
private void addFields() { private void addFields() {
if (classNode.fields == null) return; if (classNode.fields == null) return;
for (FieldNode field : classNode.fields) { for (FieldNode field : classNode.fields) {
if (recordClass && !Modifier.isStatic(field.access)) { if (recordClass && !Modifier.isStatic(field.access)) {
// proguard elevates record field access for direct record field gets // proguard elevates record field access for direct record field gets
@ -270,9 +284,11 @@ public class ClassBuilder {
continue; continue;
} }
if ((field.access & Opcodes.ACC_SYNTHETIC) != 0 || (field.access & Opcodes.ACC_MANDATED) != 0) { if ((field.access & Opcodes.ACC_SYNTHETIC) != 0 || (field.access & Opcodes.ACC_MANDATED) != 0) {
continue; // hide synthetic stuff continue; // hide synthetic stuff
} }
if ((field.access & Opcodes.ACC_ENUM) == 0) { if ((field.access & Opcodes.ACC_ENUM) == 0) {
builder.addField(new FieldBuilder(mappings, classNode, field, environment).build()); builder.addField(new FieldBuilder(mappings, classNode, field, environment).build());
} else { } else {
@ -288,6 +304,7 @@ public class ClassBuilder {
.add(field.visibleTypeAnnotations) .add(field.visibleTypeAnnotations)
.build().getBank(TypeReference.newTypeReference(TypeReference.FIELD)) .build().getBank(TypeReference.newTypeReference(TypeReference.FIELD))
.getCurrentAnnotations(); .getCurrentAnnotations();
if (!annotations.isEmpty()) { if (!annotations.isEmpty()) {
enumBuilder.addAnnotations(annotations); // no custom paths for annotations rip enumBuilder.addAnnotations(annotations); // no custom paths for annotations rip
} }
@ -301,6 +318,7 @@ public class ClassBuilder {
if (regularAnnotations == null) { if (regularAnnotations == null) {
return; return;
} }
for (AnnotationNode annotation : regularAnnotations) { for (AnnotationNode annotation : regularAnnotations) {
builder.addAnnotation(parseAnnotation(annotation)); builder.addAnnotation(parseAnnotation(annotation));
} }
@ -312,6 +330,7 @@ public class ClassBuilder {
public void addInnerClass(ClassBuilder classBuilder) { public void addInnerClass(ClassBuilder classBuilder) {
InnerClassNode innerClassNode = null; InnerClassNode innerClassNode = null;
if (classNode.innerClasses != null) { if (classNode.innerClasses != null) {
for (InnerClassNode node : classNode.innerClasses) { for (InnerClassNode node : classNode.innerClasses) {
if (node.name.equals(classBuilder.classNode.name)) { if (node.name.equals(classBuilder.classNode.name)) {
@ -339,8 +358,8 @@ public class ClassBuilder {
classBuilder.builder.modifiers.remove(javax.lang.model.element.Modifier.PUBLIC); // this modifier may come from class access classBuilder.builder.modifiers.remove(javax.lang.model.element.Modifier.PUBLIC); // this modifier may come from class access
classBuilder.builder.addModifiers(new ModifierBuilder(innerClassNode.access) classBuilder.builder.addModifiers(new ModifierBuilder(innerClassNode.access)
.checkUnseal(classBuilder.classNode, environment) .checkUnseal(classBuilder.classNode, environment)
.getModifiers(ModifierBuilder.getType(classBuilder.enumClass, classBuilder.recordClass)) .getModifiers(ModifierBuilder.getType(classBuilder.enumClass, classBuilder.recordClass)));
);
if (!Modifier.isStatic(innerClassNode.access)) { if (!Modifier.isStatic(innerClassNode.access)) {
classBuilder.instanceInner = true; classBuilder.instanceInner = true;
} }
@ -352,6 +371,7 @@ public class ClassBuilder {
sb.append(innerClassNode.innerName); // append simple name sb.append(innerClassNode.innerName); // append simple name
List<TypeVariableName> innerClassGenerics = classBuilder.signature.generics(); List<TypeVariableName> innerClassGenerics = classBuilder.signature.generics();
if (!innerClassGenerics.isEmpty()) { if (!innerClassGenerics.isEmpty()) {
sb.append("<"); sb.append("<");
for (TypeVariableName each : innerClassGenerics) { for (TypeVariableName each : innerClassGenerics) {
@ -359,9 +379,11 @@ public class ClassBuilder {
} }
sb.append(">"); sb.append(">");
} }
classBuilder.receiverSignature = sb.toString(); classBuilder.receiverSignature = sb.toString();
} }
} }
innerClasses.add(classBuilder); innerClasses.add(classBuilder);
} }
@ -370,9 +392,10 @@ public class ClassBuilder {
} }
public TypeSpec build() { public TypeSpec build() {
innerClasses.stream() for (ClassBuilder innerCb : innerClasses) {
.map(ClassBuilder::build) builder.addType(innerCb.build());
.forEach(builder::addType); }
return builder.build(); return builder.build();
} }
} }

View File

@ -15,17 +15,6 @@
*/ */
package net.fabricmc.mappingpoet; package net.fabricmc.mappingpoet;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.JavaFile;
import net.fabricmc.mappingpoet.Environment.ClassNamePointer;
import net.fabricmc.mappingpoet.Environment.NestedClassInfo;
import net.fabricmc.mappingpoet.signature.ClassStaticContext;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.InnerClassNode;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -50,6 +39,16 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
import java.util.jar.JarFile; import java.util.jar.JarFile;
import com.squareup.javapoet.JavaFile;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.InnerClassNode;
import net.fabricmc.mappingpoet.Environment.ClassNamePointer;
import net.fabricmc.mappingpoet.Environment.NestedClassInfo;
public class Main { public class Main {
public static void main(String[] args) { public static void main(String[] args) {
@ -66,8 +65,8 @@ public class Main {
if (Files.exists(outputDirectory)) { if (Files.exists(outputDirectory)) {
try (var stream = Files.walk(outputDirectory)) { try (var stream = Files.walk(outputDirectory)) {
stream.sorted(Comparator.reverseOrder()) stream.sorted(Comparator.reverseOrder())
.map(Path::toFile) .map(Path::toFile)
.forEach(File::delete); .forEach(File::delete);
} }
} }
@ -94,20 +93,20 @@ public class Main {
Map<String, ClassBuilder> classes = new HashMap<>(); Map<String, ClassBuilder> classes = new HashMap<>();
forEachClass(inputJar, (classNode, environment) -> writeClass(mapping, classNode, classes, environment), librariesDir); forEachClass(inputJar, (classNode, environment) -> writeClass(mapping, classNode, classes, environment), librariesDir);
classes.values().stream() for (ClassBuilder classBuilder : classes.values()) {
.filter(classBuilder -> !classBuilder.getClassName().contains("$")) String name = classBuilder.getClassName();
.forEach(classBuilder -> { if (name.contains("$")) continue;
int packageEnd = classBuilder.getClassName().lastIndexOf("/");
JavaFile javaFile = JavaFile.builder(packageEnd == -1 ? "" : classBuilder.getClassName().substring(0, packageEnd).replaceAll("/", "."), classBuilder.build())
.build();
try {
javaFile.writeTo(outputDirectory);
} catch (IOException e) {
throw new RuntimeException("Failed to write class", e);
}
});
try {
int packageEnd = classBuilder.getClassName().lastIndexOf("/");
String pkgName = packageEnd < 0 ? "" : classBuilder.getClassName().substring(0, packageEnd).replaceAll("/", ".");
JavaFile javaFile = JavaFile.builder(pkgName, classBuilder.build()).build();
javaFile.writeTo(outputDirectory);
} catch (Throwable t) {
throw new RuntimeException("Failed to process class "+name, t);
}
}
} }
private static void forEachClass(Path jar, ClassNodeConsumer classNodeConsumer, Path librariesDir) { private static void forEachClass(Path jar, ClassNodeConsumer classNodeConsumer, Path librariesDir) {
@ -170,7 +169,9 @@ public class Main {
//Sort all the classes making sure that inner classes come after the parent classes //Sort all the classes making sure that inner classes come after the parent classes
classes.sort(Comparator.comparing(o -> o.name)); classes.sort(Comparator.comparing(o -> o.name));
classes.forEach(node -> classNodeConsumer.accept(node, new Environment(supers, sealedClasses, nestedClasses))); for (ClassNode node : classes) {
classNodeConsumer.accept(node, new Environment(supers, sealedClasses, nestedClasses));
}
} }
private static void scanNestedClasses(Map<String, ClassNamePointer> classNames, Map<String, Environment.NestedClassInfo> instanceInnerClasses, Path librariesDir) { private static void scanNestedClasses(Map<String, ClassNamePointer> classNames, Map<String, Environment.NestedClassInfo> instanceInnerClasses, Path librariesDir) {