From 56e6b2c1c1f45f13cf97b9fd5c450836a6aca331 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Fri, 3 May 2024 19:19:41 +0900 Subject: [PATCH] Fix typo and clean up the method --- .../MethodInheritanceMappingsMigrator.java | 91 +++++++++++-------- 1 file changed, 51 insertions(+), 40 deletions(-) diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/forge/MethodInheritanceMappingsMigrator.java b/src/main/java/net/fabricmc/loom/configuration/providers/forge/MethodInheritanceMappingsMigrator.java index 96fa432d..e3922d44 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/forge/MethodInheritanceMappingsMigrator.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/forge/MethodInheritanceMappingsMigrator.java @@ -123,6 +123,52 @@ public final class MethodInheritanceMappingsMigrator implements MappingsMigrator MappingReader.read(reader, new MappingSourceNsSwitch(mappings, patchedNs)); } + Pair, Set> collected = collectClassesAndMethods(jars); + Multimap classInheritanceMap = collected.left(); + Set methods = collected.right(); + + Multimap> overriddenIntermediaries = Multimaps.newSetMultimap(new HashMap<>(), LinkedHashSet::new); + + for (MethodKey method : methods) { + // First check if the method is in the mappings, and as a different intermediary name + MappingTree.ClassMapping aClass = mappings.getClass(method.className()); + if (aClass == null) continue; + MappingTree.MethodMapping aMethod = aClass.getMethod(method.name(), method.descriptor()); + if (aMethod == null) continue; + String intermediaryName = aMethod.getName(MappingsNamespace.INTERMEDIARY.toString()); + if (intermediaryName == null || Objects.equals(intermediaryName, method.name())) continue; + + for (String superClass : classInheritanceMap.get(method.className())) { + if (methods.contains(new MethodKey(superClass, method.name(), method.descriptor()))) { + if (mappings.getClass(superClass) == null) { + // We will collect these methods here, and remove them later + // if there are more than intermediary name for the same method + String intermediaryDesc = aMethod.getDesc(MappingsNamespace.INTERMEDIARY.toString()); + overriddenIntermediaries.put(new MethodKey(superClass, method.name(), method.descriptor()), new Pair<>(intermediaryName, intermediaryDesc)); + } + } + } + } + + Set> methodsToRemove = new HashSet<>(); + + for (Map.Entry>> entry : overriddenIntermediaries.asMap().entrySet()) { + if (entry.getValue().size() >= 2) { + // We should remove these names from the mappings + // as the particular method is inherited by multiple different intermediary names + for (Pair pair : entry.getValue()) { + methodsToRemove.add(pair); + logger.info("Removing method {}{} from the mappings", pair.left(), pair.right()); + } + + break; + } + } + + return methodsToRemove; + } + + private static Pair, Set> collectClassesAndMethods(Iterable jars) throws IOException { Multimap classInheritanceMap = Multimaps.newSetMultimap(new HashMap<>(), LinkedHashSet::new); Set methods = new HashSet<>(); Visitor visitor = new Visitor(Opcodes.ASM9, classInheritanceMap, methods); @@ -138,54 +184,19 @@ public final class MethodInheritanceMappingsMigrator implements MappingsMigrator } // Populate class inheritance - Multimap newClassInheritanceMap = Multimaps.newSetMultimap(new HashMap<>(), LinkedHashSet::new); - classInheritanceMap.asMap().entrySet().stream().map(entry -> { - // Collect all super classes, and their super classes, and so on + Multimap classes = Multimaps.newSetMultimap(new HashMap<>(), LinkedHashSet::new); + + for (Map.Entry> entry : classInheritanceMap.asMap().entrySet()) { Set allSuperClasses = new HashSet<>(); for (String superClass : entry.getValue()) { collectSuperClasses(superClass, new HashSet<>(), allSuperClasses, classInheritanceMap); } - return Map.entry(entry.getKey(), allSuperClasses); - }) - .forEach(e -> newClassInheritanceMap.putAll(e.getKey(), e.getValue())); - - Set> methodsToRemove = new HashSet<>(); - Multimap> overridenIntermedaries = Multimaps.newSetMultimap(new HashMap<>(), LinkedHashSet::new); - - for (MethodKey method : methods) { - // First check if the method is in the mappings, and as a different intermediary name - MappingTree.ClassMapping aClass = mappings.getClass(method.className()); - if (aClass == null) continue; - MappingTree.MethodMapping aMethod = aClass.getMethod(method.name(), method.descriptor()); - if (aMethod == null) continue; - String intermediaryName = aMethod.getName(MappingsNamespace.INTERMEDIARY.toString()); - if (intermediaryName == null || Objects.equals(intermediaryName, method.name())) continue; - - for (String superClass : newClassInheritanceMap.get(method.className())) { - if (methods.contains(new MethodKey(superClass, method.name(), method.descriptor()))) { - if (mappings.getClass(superClass) == null) { - String intermediaryDesc = aMethod.getDesc(MappingsNamespace.INTERMEDIARY.toString()); - overridenIntermedaries.put(new MethodKey(superClass, method.name(), method.descriptor()), new Pair<>(intermediaryName, intermediaryDesc)); - } - } - } + classes.putAll(entry.getKey(), allSuperClasses); } - for (Map.Entry>> entry : overridenIntermedaries.asMap().entrySet()) { - if (entry.getValue().size() >= 2) { - // We should remove these names from the mappings - for (Pair pair : entry.getValue()) { - methodsToRemove.add(pair); - logger.info("Removing method {}{} from the mappings", pair.left(), pair.right()); - } - - break; - } - } - - return methodsToRemove; + return new Pair<>(classes, methods); } private static void collectSuperClasses(String className, Set travelled, Set allSuperClasses, Multimap classInheritanceMap) {