mirror of https://github.com/FabricMC/yarn.git
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:
parent
8b0f70e572
commit
7efbd4534e
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue