From 40a0d19adec824d0fbb23f4ee0fa0a758e86275e Mon Sep 17 00:00:00 2001 From: liach Date: Fri, 5 May 2023 17:04:07 -0500 Subject: [PATCH] 0.4.0 Migrate to mapping io, use spotless still need to work on inner class handling, need named jar inspection first --- .../filament/mappingpoet/ClassBuilder.java | 29 ++-- .../filament/mappingpoet/Environment.java | 54 ++++++ .../filament/mappingpoet/FieldBuilder.java | 8 +- .../fabricmc/filament/mappingpoet/Main.java | 68 ++++---- .../filament/mappingpoet/MappingsStore.java | 163 +++++++----------- .../filament/mappingpoet/MethodBuilder.java | 61 +++---- .../filament/mappingpoet/ModifierBuilder.java | 10 +- .../filament/mappingpoet/Signatures.java | 1 - .../mappingpoet/jd/MappingTaglet.java | 1 - .../signature/AnnotationAwareDescriptors.java | 1 - .../signature/AnnotationAwareSignatures.java | 1 - .../mappingpoet/signature/ClassSignature.java | 1 - .../signature/ClassStaticContext.java | 1 - .../signature/MethodSignature.java | 1 - .../PoetClassMethodSignatureVisitor.java | 23 ++- .../signature/PoetTypeSignatureWriter.java | 9 +- .../signature/TypeAnnotationBank.java | 1 - .../signature/TypeAnnotationMapping.java | 1 - .../signature/TypeAnnotationStorage.java | 1 - 19 files changed, 203 insertions(+), 232 deletions(-) create mode 100644 filament/src/main/java/net/fabricmc/filament/mappingpoet/Environment.java diff --git a/filament/src/main/java/net/fabricmc/filament/mappingpoet/ClassBuilder.java b/filament/src/main/java/net/fabricmc/filament/mappingpoet/ClassBuilder.java index 51a92cc917..0aa9bf3386 100644 --- a/filament/src/main/java/net/fabricmc/filament/mappingpoet/ClassBuilder.java +++ b/filament/src/main/java/net/fabricmc/filament/mappingpoet/ClassBuilder.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package net.fabricmc.mappingpoet; import com.squareup.javapoet.AnnotationSpec; @@ -24,7 +23,6 @@ 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.ClassStaticContext; import net.fabricmc.mappingpoet.signature.TypeAnnotationMapping; import net.fabricmc.mappingpoet.signature.TypeAnnotationStorage; import org.objectweb.asm.Handle; @@ -40,10 +38,7 @@ import org.objectweb.asm.tree.MethodNode; import java.lang.reflect.Modifier; import java.util.ArrayList; -import java.util.Collection; import java.util.List; -import java.util.function.Function; -import java.util.function.Predicate; import static net.fabricmc.mappingpoet.FieldBuilder.parseAnnotation; @@ -61,9 +56,7 @@ public class ClassBuilder { private final TypeSpec.Builder builder; private final List innerClasses = new ArrayList<>(); - private final Function> superGetter; - private final Predicate sealChecker; - private final ClassStaticContext context; + private final Environment environment; private final ClassSignature signature; // not really signature private final TypeAnnotationMapping typeAnnotations; @@ -75,12 +68,10 @@ public class ClassBuilder { // omits L and ; private String receiverSignature; - public ClassBuilder(MappingsStore mappings, ClassNode classNode, Function> superGetter, Predicate sealChecker, ClassStaticContext context) { + public ClassBuilder(MappingsStore mappings, ClassNode classNode, Environment environment) { this.mappings = mappings; this.classNode = classNode; - this.superGetter = superGetter; - this.sealChecker = sealChecker; - this.context = context; + this.environment = environment; this.typeAnnotations = setupAnnotations(); this.signature = setupSignature(); this.builder = setupBuilder(); @@ -141,8 +132,8 @@ public class ClassBuilder { private ClassSignature setupSignature() { return classNode.signature == null ? - AnnotationAwareDescriptors.parse(classNode.superName, classNode.interfaces, typeAnnotations, context) : - AnnotationAwareSignatures.parseClassSignature(classNode.signature, typeAnnotations, context); + AnnotationAwareDescriptors.parse(classNode.superName, classNode.interfaces, typeAnnotations, environment) : + AnnotationAwareSignatures.parseClassSignature(classNode.signature, typeAnnotations, environment); } private TypeSpec.Builder setupBuilder() { @@ -180,7 +171,7 @@ public class ClassBuilder { return builder .addModifiers(new ModifierBuilder(classNode.access) - .checkUnseal(classNode, sealChecker) + .checkUnseal(classNode, environment) .getModifiers(ModifierBuilder.getType(enumClass, recordClass)) ); } @@ -258,7 +249,7 @@ public class ClassBuilder { formalParamStartIndex = 1; // 0 this$0 } } - builder.addMethod(new MethodBuilder(mappings, classNode, method, superGetter, context, receiverSignature, formalParamStartIndex).build()); + builder.addMethod(new MethodBuilder(mappings, classNode, method, environment, receiverSignature, formalParamStartIndex).build()); } } @@ -270,7 +261,7 @@ public class ClassBuilder { if (!Modifier.isFinal(field.access) || Modifier.isProtected(field.access) || Modifier.isPublic(field.access)) { System.out.println("abnormal instance field " + field.name + " in record " + getClassName() + ", skipping"); } else { - var fieldBuilder = new FieldBuilder(mappings, classNode, field, context); + var fieldBuilder = new FieldBuilder(mappings, classNode, field, environment); var paramBuilder = ParameterSpec.builder(fieldBuilder.calculateType(), field.name); fieldBuilder.addJavaDoc(paramBuilder); fieldBuilder.addDirectAnnotations(paramBuilder); @@ -283,7 +274,7 @@ public class ClassBuilder { continue; // hide synthetic stuff } if ((field.access & Opcodes.ACC_ENUM) == 0) { - builder.addField(new FieldBuilder(mappings, classNode, field, context).build()); + builder.addField(new FieldBuilder(mappings, classNode, field, environment).build()); } else { TypeSpec.Builder enumBuilder = TypeSpec.anonymousClassBuilder(""); // jd @@ -347,7 +338,7 @@ public class ClassBuilder { classBuilder.builder.modifiers.remove(javax.lang.model.element.Modifier.PUBLIC); // this modifier may come from class access classBuilder.builder.addModifiers(new ModifierBuilder(innerClassNode.access) - .checkUnseal(classBuilder.classNode, sealChecker) + .checkUnseal(classBuilder.classNode, environment) .getModifiers(ModifierBuilder.getType(classBuilder.enumClass, classBuilder.recordClass)) ); if (!Modifier.isStatic(innerClassNode.access)) { diff --git a/filament/src/main/java/net/fabricmc/filament/mappingpoet/Environment.java b/filament/src/main/java/net/fabricmc/filament/mappingpoet/Environment.java new file mode 100644 index 0000000000..5355634b2f --- /dev/null +++ b/filament/src/main/java/net/fabricmc/filament/mappingpoet/Environment.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2020 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.fabricmc.mappingpoet; + +import com.squareup.javapoet.ClassName; +import net.fabricmc.mappingpoet.signature.ClassStaticContext; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +/** + * Represents an overall runtime environment, knows all inner class, + * super class, etc. information. + */ +public record Environment( + Map> superTypes, + Set sealedClasses, + // declaring classes keep track of namable inner classes + // and local/anon classes in whole codebase + Map declaringClasses +) implements ClassStaticContext { + public record NestedClassInfo(String declaringClass, boolean instanceInner, String simpleName) { + // two strings are nullable + } + + public record ClassNamePointer(String simple, String outerClass) { + public ClassName toClassName(ClassName outerClassName) { + if (simple == null) + return null; + + return outerClassName.nestedClass(simple); + } + } + + @Override + public boolean isInstanceInner(String internalName) { + var info = declaringClasses.get(internalName); + return info != null && info.declaringClass != null && info.instanceInner; + } +} diff --git a/filament/src/main/java/net/fabricmc/filament/mappingpoet/FieldBuilder.java b/filament/src/main/java/net/fabricmc/filament/mappingpoet/FieldBuilder.java index c069c6718f..1bf98c93a6 100644 --- a/filament/src/main/java/net/fabricmc/filament/mappingpoet/FieldBuilder.java +++ b/filament/src/main/java/net/fabricmc/filament/mappingpoet/FieldBuilder.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package net.fabricmc.mappingpoet; import com.squareup.javapoet.AnnotationSpec; @@ -24,7 +23,6 @@ import com.squareup.javapoet.FieldSpec; import com.squareup.javapoet.ParameterSpec; import com.squareup.javapoet.TypeName; import com.squareup.javapoet.TypeSpec; -import net.fabricmc.mapping.util.EntryTriple; import net.fabricmc.mappingpoet.signature.AnnotationAwareDescriptors; import net.fabricmc.mappingpoet.signature.AnnotationAwareSignatures; import net.fabricmc.mappingpoet.signature.ClassStaticContext; @@ -69,7 +67,7 @@ public class FieldBuilder { } static void addFieldJavaDoc(TypeSpec.Builder enumBuilder, MappingsStore mappings, ClassNode classNode, FieldNode fieldNode) { - mappings.addFieldDoc(enumBuilder::addJavadoc, new EntryTriple(classNode.name, fieldNode.name, fieldNode.desc)); + mappings.addFieldDoc(enumBuilder::addJavadoc, classNode.name, fieldNode.name, fieldNode.desc); } public static AnnotationSpec parseAnnotation(AnnotationNode annotation) { @@ -468,11 +466,11 @@ public class FieldBuilder { } private void addJavaDoc() { - mappings.addFieldDoc(builder::addJavadoc, new EntryTriple(classNode.name, fieldNode.name, fieldNode.desc)); + mappings.addFieldDoc(builder::addJavadoc, classNode.name, fieldNode.name, fieldNode.desc); } void addJavaDoc(ParameterSpec.Builder paramBuilder) { - mappings.addFieldDoc(paramBuilder::addJavadoc, new EntryTriple(classNode.name, fieldNode.name, fieldNode.desc)); + mappings.addFieldDoc(paramBuilder::addJavadoc, classNode.name, fieldNode.name, fieldNode.desc); } private void addDirectAnnotations() { diff --git a/filament/src/main/java/net/fabricmc/filament/mappingpoet/Main.java b/filament/src/main/java/net/fabricmc/filament/mappingpoet/Main.java index 31a83cf49c..83c614bd68 100644 --- a/filament/src/main/java/net/fabricmc/filament/mappingpoet/Main.java +++ b/filament/src/main/java/net/fabricmc/filament/mappingpoet/Main.java @@ -13,10 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - 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; @@ -37,7 +39,6 @@ import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.Comparator; import java.util.Enumeration; import java.util.HashMap; @@ -46,8 +47,6 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Function; -import java.util.function.Predicate; import java.util.jar.JarEntry; import java.util.jar.JarFile; @@ -65,15 +64,16 @@ public class Main { try { if (Files.exists(outputDirectory)) { - Files.walk(outputDirectory) - .sorted(Comparator.reverseOrder()) - .map(Path::toFile) - .forEach(File::delete); + try (var stream = Files.walk(outputDirectory)) { + stream.sorted(Comparator.reverseOrder()) + .map(Path::toFile) + .forEach(File::delete); + } } Files.createDirectories(outputDirectory); } catch (IOException e) { - e.printStackTrace(); + throw new UncheckedIOException(e); } if (!Files.exists(mappings)) { @@ -92,7 +92,7 @@ public class Main { public static void generate(Path mappings, Path inputJar, Path outputDirectory, Path librariesDir) { final MappingsStore mapping = new MappingsStore(mappings); Map classes = new HashMap<>(); - forEachClass(inputJar, (superGetter, classNode, context, sealChecker) -> writeClass(mapping, classNode, classes, superGetter, sealChecker, context), librariesDir); + forEachClass(inputJar, (classNode, environment) -> writeClass(mapping, classNode, classes, environment), librariesDir); classes.values().stream() .filter(classBuilder -> !classBuilder.getClassName().contains("$")) @@ -115,10 +115,11 @@ public class Main { Map> supers = new HashMap<>(); Set sealedClasses = new HashSet<>(); // their subclsses/impls need non-sealed modifier - Map instanceInnerClasses = new ConcurrentHashMap<>(); + Map nestedClasses = new ConcurrentHashMap<>(); + Map classNames = new ConcurrentHashMap<>(); if (librariesDir != null) { - scanInnerClasses(instanceInnerClasses, librariesDir); + scanNestedClasses(classNames, nestedClasses, librariesDir); } try (final JarFile jarFile = new JarFile(jar.toFile())) { @@ -148,7 +149,10 @@ public class Main { if (classNode.innerClasses != null) { for (InnerClassNode e : classNode.innerClasses) { - instanceInnerClasses.put(e.name, !Modifier.isStatic(e.access)); + if (e.outerName != null) { + // null -> declared in method/initializer + nestedClasses.put(e.name, new NestedClassInfo(e.outerName, !Modifier.isStatic(e.access), e.innerName)); + } } } @@ -166,12 +170,10 @@ public class Main { //Sort all the classes making sure that inner classes come after the parent classes classes.sort(Comparator.comparing(o -> o.name)); - ClassStaticContext innerClassContext = new InnerClassStats(instanceInnerClasses); - Function> superGetter = k -> supers.getOrDefault(k, Collections.emptyList()); - classes.forEach(node -> classNodeConsumer.accept(superGetter, node, innerClassContext, sealedClasses::contains)); + classes.forEach(node -> classNodeConsumer.accept(node, new Environment(supers, sealedClasses, nestedClasses))); } - private static void scanInnerClasses(Map instanceInnerClasses, Path librariesDir) { + private static void scanNestedClasses(Map classNames, Map instanceInnerClasses, Path librariesDir) { try { Files.walkFileTree(librariesDir, new SimpleFileVisitor<>() { @Override @@ -194,8 +196,11 @@ public class Main { ClassReader reader = new ClassReader(is); reader.accept(new ClassVisitor(Opcodes.ASM8) { @Override - public void visitInnerClass(String name, String outerName, String innerName, int access) { - instanceInnerClasses.put(name, !Modifier.isStatic(access)); + public void visitInnerClass(String name, String outerName, String simpleName, int access) { + instanceInnerClasses.put(name, new Environment.NestedClassInfo(outerName, !Modifier.isStatic(access), simpleName)); + if (outerName != null) { + classNames.put(name, new ClassNamePointer(simpleName, outerName)); + } } }, ClassReader.SKIP_CODE); } @@ -225,7 +230,8 @@ public class Main { return ch >= '0' && ch <= '9'; } - private static void writeClass(MappingsStore mappings, ClassNode classNode, Map existingClasses, Function> superGetter, Predicate sealChecker, ClassStaticContext context) { + private static void writeClass(MappingsStore mappings, ClassNode classNode, Map existingClasses, Environment environment) { + // TODO make sure named jar has valid InnerClasses, use that info instead String name = classNode.name; { //Block anonymous class and their nested classes @@ -239,7 +245,8 @@ public class Main { } } - ClassBuilder classBuilder = new ClassBuilder(mappings, classNode, superGetter, sealChecker, context); + // TODO: ensure InnerClasses is remapped, and create ClassName from parent class name + ClassBuilder classBuilder = new ClassBuilder(mappings, classNode, environment); if (name.contains("$")) { String parentClass = name.substring(0, name.lastIndexOf("$")); @@ -256,23 +263,6 @@ public class Main { @FunctionalInterface private interface ClassNodeConsumer { - void accept(Function> superGetter, ClassNode node, ClassStaticContext staticContext, Predicate sealedChecker); - } - - private static final class InnerClassStats implements ClassStaticContext { - final Map instanceInnerClasses; - - InnerClassStats(Map instanceInnerClasses) { - this.instanceInnerClasses = instanceInnerClasses; - } - - @Override - public boolean isInstanceInner(String internalName) { - if (internalName.indexOf('$') == -1) { - return false; // heuristics - } - - return instanceInnerClasses.computeIfAbsent(internalName, Main::isInstanceInnerOnClasspath); - } + void accept(ClassNode node, Environment environment); } } diff --git a/filament/src/main/java/net/fabricmc/filament/mappingpoet/MappingsStore.java b/filament/src/main/java/net/fabricmc/filament/mappingpoet/MappingsStore.java index cf87506c2e..84abd70f96 100644 --- a/filament/src/main/java/net/fabricmc/filament/mappingpoet/MappingsStore.java +++ b/filament/src/main/java/net/fabricmc/filament/mappingpoet/MappingsStore.java @@ -13,71 +13,46 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package net.fabricmc.mappingpoet; -import java.io.BufferedReader; +import net.fabricmc.mappingio.MappingReader; +import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch; +import net.fabricmc.mappingio.format.MappingFormat; +import net.fabricmc.mappingio.tree.MappingTreeView; +import net.fabricmc.mappingio.tree.MappingTreeView.ClassMappingView; +import net.fabricmc.mappingio.tree.MappingTreeView.ElementMappingView; +import net.fabricmc.mappingio.tree.MappingTreeView.MethodMappingView; +import net.fabricmc.mappingio.tree.MemoryMappingTree; + import java.io.IOException; -import java.nio.file.Files; import java.nio.file.Path; -import java.util.AbstractMap; -import java.util.Collection; -import java.util.HashMap; +import java.util.AbstractMap.SimpleImmutableEntry; import java.util.List; import java.util.Map; -import java.util.function.Function; -import net.fabricmc.mapping.tree.ClassDef; -import net.fabricmc.mapping.tree.FieldDef; -import net.fabricmc.mapping.tree.Mapped; -import net.fabricmc.mapping.tree.MethodDef; -import net.fabricmc.mapping.tree.TinyMappingFactory; -import net.fabricmc.mapping.tree.TinyTree; -import net.fabricmc.mapping.util.EntryTriple; +import static net.fabricmc.mappingio.tree.MappingTreeView.SRC_NAMESPACE_ID; //Taken from loom public class MappingsStore { - private final Map classes = new HashMap<>(); - private final Map fields = new HashMap<>(); - private final Map> methods = new HashMap<>(); - - private final String namespace = "named"; - private final List namespaces; + private final MappingTreeView tree; + private final int maxNamespace; public MappingsStore(Path tinyFile) { - final TinyTree mappings = readMappings(tinyFile); - - namespaces = mappings.getMetadata().getNamespaces(); - - for (ClassDef classDef : mappings.getClasses()) { - final String className = classDef.getName(namespace); - classes.put(className, classDef); - - for (FieldDef fieldDef : classDef.getFields()) { - fields.put(new EntryTriple(className, fieldDef.getName(namespace), fieldDef.getDescriptor(namespace)), fieldDef); - } - - for (MethodDef methodDef : classDef.getMethods()) { - methods.put(new EntryTriple(className, methodDef.getName(namespace), methodDef.getDescriptor(namespace)), new AbstractMap.SimpleImmutableEntry<>(className, methodDef)); - } - } + this.tree = readMappings(tinyFile); + this.maxNamespace = tree.getMaxNamespaceId(); } - private static TinyTree readMappings(Path input) { - try (BufferedReader reader = Files.newBufferedReader(input)) { - return TinyMappingFactory.loadWithDetection(reader); + private static MappingTreeView readMappings(Path input) { + var tree = new MemoryMappingTree(); + try { + MappingReader.read(input, MappingFormat.TINY_2, new MappingSourceNsSwitch(tree, "named")); } catch (IOException e) { throw new RuntimeException("Failed to read mappings", e); } + return tree; } - @Deprecated - public String getClassDoc(String className) { - ClassDef classDef = classes.get(className); - return classDef != null ? classDef.getComment() : null; - } - - private void addDoc(Mapped element, DocAdder adder) { + private void addDoc(ElementMappingView element, DocAdder adder) { String doc = element.getComment(); if (doc != null) { adder.addJavadoc("$L", doc); @@ -85,109 +60,95 @@ public class MappingsStore { } public void addClassDoc(DocAdder adder, String className) { - ClassDef classDef = classes.get(className); + var classDef = tree.getClass(className); if (classDef == null) { return; } addDoc(classDef, adder); adder.addJavadoc("\n"); - for (String namespace : namespaces) { - String transformedName = classDef.getName(namespace); - adder.addJavadoc("@mapping {@literal $L:$L}\n", namespace, transformedName); + for (int id = SRC_NAMESPACE_ID; id < maxNamespace; id++) { + String transformedName = classDef.getName(id); + adder.addJavadoc("@mapping {@literal $L:$L}\n", tree.getNamespaceName(id), transformedName); } } - @Deprecated - public String getFieldDoc(EntryTriple fieldEntry) { - FieldDef fieldDef = fields.get(fieldEntry); - return fieldDef != null ? fieldDef.getComment() : null; - } + public void addFieldDoc(DocAdder addJavadoc, String owner, String name, String desc) { + var classDef = tree.getClass(owner); + if (classDef == null) { + return; + } - public void addFieldDoc(DocAdder addJavadoc, EntryTriple fieldEntry) { - FieldDef fieldDef = fields.get(fieldEntry); + var fieldDef = classDef.getField(name, desc); if (fieldDef == null) { return; } addDoc(fieldDef, addJavadoc); - ClassDef owner = classes.get(fieldEntry.getOwner()); addJavadoc.addJavadoc("\n"); - for (String namespace : namespaces) { - String transformedName = fieldDef.getName(namespace); - String mixinForm = "L" + owner.getName(namespace) + ";" + transformedName + ":" + fieldDef.getDescriptor(namespace); - addJavadoc.addJavadoc("@mapping {@literal $L:$L:$L}\n", namespace, transformedName, mixinForm); + for (int id = SRC_NAMESPACE_ID; id < maxNamespace; id++) { + String transformedName = fieldDef.getName(id); + String mixinForm = "L" + classDef.getName(id) + ";" + transformedName + ":" + fieldDef.getDesc(id); + addJavadoc.addJavadoc("@mapping {@literal $L:$L:$L}\n", tree.getNamespaceName(id), transformedName, mixinForm); } } - public Map.Entry getParamNameAndDoc(Function> superGetters, EntryTriple methodEntry, int index) { - Map.Entry found = searchMethod(superGetters, methodEntry); + public Map.Entry getParamNameAndDoc(Environment environment, String owner, String name, String desc, int index) { + var found = searchMethod(environment, owner, name, desc); if (found != null) { - MethodDef methodDef = found.getValue(); - if (methodDef.getParameters().isEmpty()) { + var methodDef = found.getValue(); + if (methodDef.getArgs().isEmpty()) { return null; } - return methodDef.getParameters().stream() - .filter(param -> param.getLocalVariableIndex() == index) - .map(param -> new AbstractMap.SimpleImmutableEntry<>(param.getName(namespace), param.getComment())) + return methodDef.getArgs().stream() + .filter(param -> param.getLvIndex() == index) + // Map.entry() is null-hostile + .map(param -> new SimpleImmutableEntry<>(param.getSrcName(), param.getComment())) .findFirst() .orElse(null); } return null; } - @Deprecated - public String getMethodDoc(Function> superGetters, EntryTriple methodEntry) { - Map.Entry methodDef = searchMethod(superGetters, methodEntry); - - if (methodDef != null) { - return methodDef.getValue().getComment(); // comment doc handled separately by javapoet - } - - return null; - } - - public void addMethodDoc(DocAdder adder, Function> superGetters, EntryTriple methodEntry) { - Map.Entry found = searchMethod(superGetters, methodEntry); + public void addMethodDoc(DocAdder adder, Environment environment, String owner, String name, String desc) { + var found = searchMethod(environment, owner, name, desc); if (found == null) { return; } - MethodDef methodDef = found.getValue(); - ClassDef owner = classes.get(found.getKey()); - if (!owner.getName(namespace).equals(methodEntry.getOwner())) { + var methodDef = found.getValue(); + var ownerDef = found.getKey(); + if (!ownerDef.equals(methodDef.getOwner())) { adder.addJavadoc("{@inheritDoc}"); } else { addDoc(methodDef, adder); } adder.addJavadoc("\n"); - for (String namespace : namespaces) { - String transformedName = methodDef.getName(namespace); - String mixinForm = "L" + owner.getName(namespace) + ";" + transformedName + methodDef.getDescriptor(namespace); - adder.addJavadoc("@mapping {@literal $L:$L:$L}\n", namespace, transformedName, mixinForm); + for (int id = SRC_NAMESPACE_ID; id < maxNamespace; id++) { + String transformedName = methodDef.getName(id); + String mixinForm = "L" + ownerDef.getName(id) + ";" + transformedName + methodDef.getDesc(id); + adder.addJavadoc("@mapping {@literal $L:$L:$L}\n", tree.getNamespaceName(id), transformedName, mixinForm); } } - private Map.Entry searchMethod(Function> superGetters, EntryTriple methodEntry) { - String className = methodEntry.getOwner(); - if (!classes.containsKey(className)) { + private Map.Entry searchMethod(Environment environment, String owner, String name, String desc) { + var classDef = tree.getClass(owner); + + if (classDef == null) return null; - } - if (methods.containsKey(methodEntry)) { - return methods.get(methodEntry); // Nullable! - } + var methodDef = classDef.getMethod(name, desc); + if (methodDef != null) + return Map.entry(methodDef.getOwner(), methodDef); - for (String superName : superGetters.apply(className)) { - EntryTriple triple = new EntryTriple(superName, methodEntry.getName(), methodEntry.getDescriptor()); - Map.Entry ret = searchMethod(superGetters, triple); + + for (String superName : environment.superTypes().getOrDefault(owner, List.of())) { + var ret = searchMethod(environment, superName, name, desc); if (ret != null) { - methods.put(triple, ret); return ret; } } - methods.put(methodEntry, null); return null; } diff --git a/filament/src/main/java/net/fabricmc/filament/mappingpoet/MethodBuilder.java b/filament/src/main/java/net/fabricmc/filament/mappingpoet/MethodBuilder.java index 496844848f..afe2bc3faf 100644 --- a/filament/src/main/java/net/fabricmc/filament/mappingpoet/MethodBuilder.java +++ b/filament/src/main/java/net/fabricmc/filament/mappingpoet/MethodBuilder.java @@ -13,38 +13,31 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package net.fabricmc.mappingpoet; +import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.ParameterSpec; +import com.squareup.javapoet.TypeName; +import net.fabricmc.mappingpoet.signature.AnnotationAwareDescriptors; +import net.fabricmc.mappingpoet.signature.AnnotationAwareSignatures; +import net.fabricmc.mappingpoet.signature.MethodSignature; +import net.fabricmc.mappingpoet.signature.TypeAnnotationBank; +import net.fabricmc.mappingpoet.signature.TypeAnnotationMapping; +import net.fabricmc.mappingpoet.signature.TypeAnnotationStorage; +import org.objectweb.asm.TypeReference; +import org.objectweb.asm.tree.AnnotationNode; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.MethodNode; + +import javax.lang.model.element.Modifier; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.function.Function; - -import javax.lang.model.element.Modifier; - -import com.squareup.javapoet.MethodSpec; -import com.squareup.javapoet.ParameterSpec; -import com.squareup.javapoet.TypeName; -import org.objectweb.asm.TypeReference; -import org.objectweb.asm.tree.AnnotationNode; -import org.objectweb.asm.tree.ClassNode; -import org.objectweb.asm.tree.MethodNode; - -import net.fabricmc.mapping.util.EntryTriple; -import net.fabricmc.mappingpoet.signature.AnnotationAwareDescriptors; -import net.fabricmc.mappingpoet.signature.AnnotationAwareSignatures; -import net.fabricmc.mappingpoet.signature.ClassStaticContext; -import net.fabricmc.mappingpoet.signature.MethodSignature; -import net.fabricmc.mappingpoet.signature.TypeAnnotationBank; -import net.fabricmc.mappingpoet.signature.TypeAnnotationMapping; -import net.fabricmc.mappingpoet.signature.TypeAnnotationStorage; public class MethodBuilder { private static final Set RESERVED_KEYWORDS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList( @@ -58,20 +51,18 @@ public class MethodBuilder { private final ClassNode classNode; private final MethodNode methodNode; private final MethodSpec.Builder builder; - private final Function> superGetter; + private final Environment environment; private final int formalParamStartIndex; - private final ClassStaticContext context; private final String receiverSignature; private final TypeAnnotationMapping typeAnnotations; private MethodSignature signature; - public MethodBuilder(MappingsStore mappings, ClassNode classNode, MethodNode methodNode, Function> superGetter, ClassStaticContext context, String receiverSignature, int formalParamStartIndex) { + public MethodBuilder(MappingsStore mappings, ClassNode classNode, MethodNode methodNode, Environment environment, String receiverSignature, int formalParamStartIndex) { this.mappings = mappings; this.classNode = classNode; this.methodNode = methodNode; - this.superGetter = superGetter; - this.context = context; + this.environment = environment; this.receiverSignature = receiverSignature; this.formalParamStartIndex = formalParamStartIndex; @@ -158,7 +149,7 @@ public class MethodBuilder { } if (methodNode.signature != null) { - signature = AnnotationAwareSignatures.parseMethodSignature(methodNode.signature, typeAnnotations, context); + signature = AnnotationAwareSignatures.parseMethodSignature(methodNode.signature, typeAnnotations, environment); builder.addTypeVariables(signature.generics()); } @@ -190,7 +181,7 @@ public class MethodBuilder { typeName = signature.result(); } else { String returnDesc = methodNode.desc.substring(methodNode.desc.lastIndexOf(")") + 1); - typeName = AnnotationAwareDescriptors.parseDesc(returnDesc, typeAnnotations.getBank(TypeReference.newTypeReference(TypeReference.METHOD_RETURN)), context); + typeName = AnnotationAwareDescriptors.parseDesc(returnDesc, typeAnnotations.getBank(TypeReference.newTypeReference(TypeReference.METHOD_RETURN)), environment); } builder.returns(typeName); @@ -215,7 +206,7 @@ public class MethodBuilder { ParameterSpec.Builder receiverBuilder; // only instance inner class ctor can have receivers if (methodNode.name.equals("")) { - TypeName annotatedReceiver = AnnotationAwareSignatures.parseSignature("L" + receiverSignature.substring(0, receiverSignature.lastIndexOf('.')) + ";", receiverAnnos, context); + TypeName annotatedReceiver = AnnotationAwareSignatures.parseSignature("L" + receiverSignature.substring(0, receiverSignature.lastIndexOf('.')) + ";", receiverAnnos, environment); // vulnerable heuristics String simpleNameChain = classNode.name.substring(classNode.name.lastIndexOf('/') + 1); int part1 = simpleNameChain.lastIndexOf('$'); // def exists @@ -223,7 +214,7 @@ public class MethodBuilder { String usedName = simpleNameChain.substring(part2 + 1, part1); receiverBuilder = ParameterSpec.builder(annotatedReceiver, usedName + ".this"); } else { - TypeName annotatedReceiver = AnnotationAwareSignatures.parseSignature("L" + receiverSignature + ";", receiverAnnos, context); + TypeName annotatedReceiver = AnnotationAwareSignatures.parseSignature("L" + receiverSignature + ";", receiverAnnos, environment); receiverBuilder = ParameterSpec.builder(annotatedReceiver, "this"); } // receiver param cannot have its jd/param anno except type use anno @@ -269,9 +260,9 @@ public class MethodBuilder { if (signatureParamIterator.hasNext()) { parsedType = signatureParamIterator.next(); } else { - parsedType = AnnotationAwareDescriptors.parseDesc(desc.substring(oldIndex, index), typeAnnotations.getBank(TypeReference.newFormalParameterReference(paramIndex - formalParamStartIndex)), context); + parsedType = AnnotationAwareDescriptors.parseDesc(desc.substring(oldIndex, index), typeAnnotations.getBank(TypeReference.newFormalParameterReference(paramIndex - formalParamStartIndex)), environment); } - paramTypes.add(new ParamType(mappings.getParamNameAndDoc(superGetter, new EntryTriple(classNode.name, methodNode.name, methodNode.desc), slot), parsedType, usedParamNames, slot)); + paramTypes.add(new ParamType(mappings.getParamNameAndDoc(environment, classNode.name, methodNode.name, methodNode.desc, slot), parsedType, usedParamNames, slot)); } slot++; if (nonAnnotatedParsedType.equals(TypeName.DOUBLE) || nonAnnotatedParsedType.equals(TypeName.LONG)) { @@ -298,14 +289,14 @@ public class MethodBuilder { if (exceptions != null) { int index = 0; for (String internalName : exceptions) { - builder.addException(AnnotationAwareDescriptors.parseType(internalName, typeAnnotations.getBank(TypeReference.newExceptionReference(index)), context)); + builder.addException(AnnotationAwareDescriptors.parseType(internalName, typeAnnotations.getBank(TypeReference.newExceptionReference(index)), environment)); index++; } } } private void addJavaDoc() { - mappings.addMethodDoc(builder::addJavadoc, superGetter, new EntryTriple(classNode.name, methodNode.name, methodNode.desc)); + mappings.addMethodDoc(builder::addJavadoc, environment, classNode.name, methodNode.name, methodNode.desc); } public MethodSpec build() { diff --git a/filament/src/main/java/net/fabricmc/filament/mappingpoet/ModifierBuilder.java b/filament/src/main/java/net/fabricmc/filament/mappingpoet/ModifierBuilder.java index dcc7c79ddb..926ee94895 100644 --- a/filament/src/main/java/net/fabricmc/filament/mappingpoet/ModifierBuilder.java +++ b/filament/src/main/java/net/fabricmc/filament/mappingpoet/ModifierBuilder.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package net.fabricmc.mappingpoet; import org.objectweb.asm.tree.ClassNode; @@ -21,7 +20,6 @@ import org.objectweb.asm.tree.ClassNode; import javax.lang.model.element.Modifier; import java.util.ArrayList; import java.util.List; -import java.util.function.Predicate; public class ModifierBuilder { @@ -32,21 +30,21 @@ public class ModifierBuilder { this.access = access; } - public ModifierBuilder checkUnseal(ClassNode node, Predicate sealChecker) { + public ModifierBuilder checkUnseal(ClassNode node, Environment env) { if (java.lang.reflect.Modifier.isFinal(node.access)) { return this; } if (node.interfaces != null) { for (String itf : node.interfaces) { - if (sealChecker.test(itf)) { + if (env.sealedClasses().contains(itf)) { needsUnseal = true; return this; } } } - if (node.superName != null && sealChecker.test(node.superName)) { + if (node.superName != null && env.sealedClasses().contains(node.superName)) { needsUnseal = true; } @@ -98,7 +96,7 @@ public class ModifierBuilder { modifiers.add(Modifier.NATIVE); } if (java.lang.reflect.Modifier.isStrict(access)) { - modifiers.add(Modifier.STRICTFP); + modifiers.add(Modifier.STRICTFP); // obsolete as of Java 17 } if (needsUnseal && type == Type.CLASS) { diff --git a/filament/src/main/java/net/fabricmc/filament/mappingpoet/Signatures.java b/filament/src/main/java/net/fabricmc/filament/mappingpoet/Signatures.java index a4f1e82f6b..c2b996879c 100644 --- a/filament/src/main/java/net/fabricmc/filament/mappingpoet/Signatures.java +++ b/filament/src/main/java/net/fabricmc/filament/mappingpoet/Signatures.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package net.fabricmc.mappingpoet; import java.util.AbstractMap; diff --git a/filament/src/main/java/net/fabricmc/filament/mappingpoet/jd/MappingTaglet.java b/filament/src/main/java/net/fabricmc/filament/mappingpoet/jd/MappingTaglet.java index b2f07bdb7c..08bc6a36d7 100644 --- a/filament/src/main/java/net/fabricmc/filament/mappingpoet/jd/MappingTaglet.java +++ b/filament/src/main/java/net/fabricmc/filament/mappingpoet/jd/MappingTaglet.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package net.fabricmc.mappingpoet.jd; import java.util.EnumSet; diff --git a/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/AnnotationAwareDescriptors.java b/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/AnnotationAwareDescriptors.java index decf8ae66f..c845c8d656 100644 --- a/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/AnnotationAwareDescriptors.java +++ b/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/AnnotationAwareDescriptors.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package net.fabricmc.mappingpoet.signature; import java.util.AbstractMap; diff --git a/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/AnnotationAwareSignatures.java b/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/AnnotationAwareSignatures.java index c6572d68bb..d762dfc0a5 100644 --- a/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/AnnotationAwareSignatures.java +++ b/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/AnnotationAwareSignatures.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package net.fabricmc.mappingpoet.signature; import com.squareup.javapoet.TypeName; diff --git a/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/ClassSignature.java b/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/ClassSignature.java index 11b0004ffe..ab15942dcc 100644 --- a/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/ClassSignature.java +++ b/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/ClassSignature.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package net.fabricmc.mappingpoet.signature; import java.util.List; diff --git a/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/ClassStaticContext.java b/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/ClassStaticContext.java index c1933e5b72..22e0536280 100644 --- a/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/ClassStaticContext.java +++ b/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/ClassStaticContext.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package net.fabricmc.mappingpoet.signature; /** diff --git a/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/MethodSignature.java b/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/MethodSignature.java index 69762419c3..bea2f7222e 100644 --- a/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/MethodSignature.java +++ b/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/MethodSignature.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package net.fabricmc.mappingpoet.signature; import java.util.List; diff --git a/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/PoetClassMethodSignatureVisitor.java b/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/PoetClassMethodSignatureVisitor.java index 1c6056dc79..eec5be758d 100644 --- a/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/PoetClassMethodSignatureVisitor.java +++ b/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/PoetClassMethodSignatureVisitor.java @@ -13,10 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package net.fabricmc.mappingpoet.signature; -import java.util.LinkedList; +import java.util.ArrayList; import com.squareup.javapoet.TypeName; import com.squareup.javapoet.TypeVariableName; @@ -29,20 +28,20 @@ public final class PoetClassMethodSignatureVisitor extends SignatureVisitor { private final TypeAnnotationMapping mapping; private final ClassStaticContext context; private final boolean forClass; - LinkedList generics = new LinkedList<>(); + ArrayList generics = new ArrayList<>(); // collecting generic String currentGenericName; - LinkedList currentGenericBounds = new LinkedList<>(); + ArrayList currentGenericBounds = new ArrayList<>(); // bound for each generic PoetTypeSignatureWriter pendingLowerBound; // classes usage - LinkedList superTypes = new LinkedList<>(); + ArrayList superTypes = new ArrayList<>(); PoetTypeSignatureWriter pendingSupertype; // methods usage - LinkedList params = new LinkedList<>(); - LinkedList throwables = new LinkedList<>(); + ArrayList params = new ArrayList<>(); + ArrayList throwables = new ArrayList<>(); PoetTypeSignatureWriter pendingSlot; TypeName returnType; @@ -84,7 +83,7 @@ public final class PoetClassMethodSignatureVisitor extends SignatureVisitor { private void collectLowerBound() { if (pendingLowerBound != null) { - currentGenericBounds.addLast(pendingLowerBound.compute()); + currentGenericBounds.add(pendingLowerBound.compute()); pendingLowerBound = null; } } @@ -113,7 +112,7 @@ public final class PoetClassMethodSignatureVisitor extends SignatureVisitor { private void collectSupertype() { if (pendingSupertype != null) { TypeName simple = pendingSupertype.compute(); - superTypes.addLast(simple); + superTypes.add(simple); pendingSupertype = null; } @@ -139,7 +138,7 @@ public final class PoetClassMethodSignatureVisitor extends SignatureVisitor { public ClassSignature collectClass() { collectSupertype(); - TypeName superclass = superTypes.removeFirst(); + TypeName superclass = superTypes.remove(0); return new ClassSignature(generics, superclass, superTypes); } @@ -148,7 +147,7 @@ public final class PoetClassMethodSignatureVisitor extends SignatureVisitor { private void collectParam() { if (pendingSlot != null) { TypeName slot = pendingSlot.compute(); - params.addLast(slot); + params.add(slot); pendingSlot = null; } @@ -159,7 +158,7 @@ public final class PoetClassMethodSignatureVisitor extends SignatureVisitor { if (returnType == null) { returnType = pendingSlot.compute(); } else { - throwables.addLast(pendingSlot.compute()); + throwables.add(pendingSlot.compute()); } pendingSlot = null; diff --git a/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/PoetTypeSignatureWriter.java b/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/PoetTypeSignatureWriter.java index 1d36b731e2..ab8bff2dc5 100644 --- a/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/PoetTypeSignatureWriter.java +++ b/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/PoetTypeSignatureWriter.java @@ -13,10 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package net.fabricmc.mappingpoet.signature; -import java.util.LinkedList; +import java.util.ArrayList; import java.util.Map; import java.util.Objects; @@ -42,7 +41,7 @@ import net.fabricmc.mappingpoet.Signatures; public final class PoetTypeSignatureWriter extends SignatureVisitor { private final ClassStaticContext context; - private final LinkedList params = new LinkedList<>(); + private final ArrayList params = new ArrayList<>(); private /* NonNull */ TypeAnnotationBank storage; // mutable private TypeName result; // array @@ -158,7 +157,7 @@ public final class PoetTypeSignatureWriter extends SignatureVisitor { }; used = AnnotationAwareDescriptors.annotate(used, storage.advance(TypePath.TYPE_ARGUMENT, params.size())); - params.addLast(used); + params.add(used); activeTypeArgument = null; activeTypeArgumentKind = 0; @@ -172,7 +171,7 @@ public final class PoetTypeSignatureWriter extends SignatureVisitor { TypeName used = WildcardTypeName.subtypeOf(TypeName.OBJECT); used = AnnotationAwareDescriptors.annotate(used, storage.advance(TypePath.TYPE_ARGUMENT, params.size())); - params.addLast(used); + params.add(used); } // (? extends/ ? super)? ClassType like in Consumer, diff --git a/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/TypeAnnotationBank.java b/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/TypeAnnotationBank.java index 3b24907c2b..2a26517d47 100644 --- a/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/TypeAnnotationBank.java +++ b/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/TypeAnnotationBank.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package net.fabricmc.mappingpoet.signature; import java.util.Collections; diff --git a/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/TypeAnnotationMapping.java b/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/TypeAnnotationMapping.java index f6caaaee05..340cd25e16 100644 --- a/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/TypeAnnotationMapping.java +++ b/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/TypeAnnotationMapping.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package net.fabricmc.mappingpoet.signature; import org.objectweb.asm.TypeReference; diff --git a/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/TypeAnnotationStorage.java b/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/TypeAnnotationStorage.java index 14af548b4d..c1322661e0 100644 --- a/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/TypeAnnotationStorage.java +++ b/filament/src/main/java/net/fabricmc/filament/mappingpoet/signature/TypeAnnotationStorage.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package net.fabricmc.mappingpoet.signature; import java.util.ArrayList;