From 867793d8c31bfc42c9b88d70565f6c857ed965db Mon Sep 17 00:00:00 2001 From: qwertyuioplkjhgfd <45241413+qwertyuioplkjhgfd@users.noreply.github.com> Date: Tue, 27 Jun 2023 06:16:40 -0700 Subject: [PATCH] Fix constructor mappings with layered mappings (#881) * add AddConstructorMappingVisitor * add constructor test * Update src/main/java/net/fabricmc/loom/configuration/providers/mappings/utils/AddConstructorMappingVisitor.java Co-authored-by: Juuz <6596629+Juuxel@users.noreply.github.com> * apply requested changes --------- Co-authored-by: qwertyuioplkjhgfd Co-authored-by: Juuz <6596629+Juuxel@users.noreply.github.com> --- .../mappings/LayeredMappingsDependency.java | 4 +- .../utils/AddConstructorMappingVisitor.java | 85 +++++++++++++++++++ .../LayeredMappingsSpecification.groovy | 4 +- .../ParchmentMappingLayerTest.groovy | 1 + 4 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/mappings/utils/AddConstructorMappingVisitor.java diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsDependency.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsDependency.java index 0b3be679..4ce75ef7 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsDependency.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsDependency.java @@ -49,6 +49,7 @@ import net.fabricmc.loom.api.mappings.layered.MappingContext; import net.fabricmc.loom.api.mappings.layered.MappingLayer; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; import net.fabricmc.loom.configuration.providers.mappings.extras.unpick.UnpickLayer; +import net.fabricmc.loom.configuration.providers.mappings.utils.AddConstructorMappingVisitor; import net.fabricmc.loom.util.ZipUtils; import net.fabricmc.mappingio.adapter.MappingDstNsReorder; import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch; @@ -102,7 +103,8 @@ public class LayeredMappingsDependency implements SelfResolvingDependency, FileC MappingDstNsReorder nsReorder = new MappingDstNsReorder(tiny2Writer, Collections.singletonList(MappingsNamespace.NAMED.toString())); MappingSourceNsSwitch nsSwitch = new MappingSourceNsSwitch(nsReorder, MappingsNamespace.INTERMEDIARY.toString(), true); - mappings.accept(nsSwitch); + AddConstructorMappingVisitor addConstructor = new AddConstructorMappingVisitor(nsSwitch); + mappings.accept(addConstructor); Files.deleteIfExists(mappingsFile); ZipUtils.add(mappingsFile, "mappings/mappings.tiny", writer.toString().getBytes(StandardCharsets.UTF_8)); diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/utils/AddConstructorMappingVisitor.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/utils/AddConstructorMappingVisitor.java new file mode 100644 index 00000000..8052ed69 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/utils/AddConstructorMappingVisitor.java @@ -0,0 +1,85 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2021 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.configuration.providers.mappings.utils; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +import net.fabricmc.mappingio.MappedElementKind; +import net.fabricmc.mappingio.MappingVisitor; +import net.fabricmc.mappingio.adapter.ForwardingMappingVisitor; + +/** + * Adds the constructor method {@code } to the destination namespaces, + * as long as the source name is {@code } and the destination mapping is null. + */ +public class AddConstructorMappingVisitor extends ForwardingMappingVisitor { + private boolean inConstructor; + private boolean[] namespaceVisited; + + public AddConstructorMappingVisitor(MappingVisitor next) { + super(next); + } + + @Override + public void visitNamespaces(String srcNamespace, List dstNamespaces) throws IOException { + namespaceVisited = new boolean[dstNamespaces.size()]; + super.visitNamespaces(srcNamespace, dstNamespaces); + } + + @Override + public boolean visitMethod(String srcName, String srcDesc) throws IOException { + if ("".equals(srcName)) { + inConstructor = true; + Arrays.fill(namespaceVisited, false); + } else { + inConstructor = false; + } + + return super.visitMethod(srcName, srcDesc); + } + + @Override + public boolean visitElementContent(MappedElementKind targetKind) throws IOException { + if (inConstructor) { + inConstructor = false; + + for (int i = 0; i < namespaceVisited.length; i++) { + if (!namespaceVisited[i]) { + visitDstName(targetKind, i, ""); + } + } + } + + return super.visitElementContent(targetKind); + } + + @Override + public void visitDstName(MappedElementKind targetKind, int namespace, String name) throws IOException { + namespaceVisited[namespace] = true; + super.visitDstName(targetKind, namespace, name); + } +} diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingsSpecification.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingsSpecification.groovy index 1b9d1836..17273f22 100644 --- a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingsSpecification.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingsSpecification.groovy @@ -41,6 +41,7 @@ import net.fabricmc.loom.configuration.providers.mappings.IntermediateMappingsSe import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpec import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingsProcessor import net.fabricmc.loom.configuration.providers.mappings.extras.unpick.UnpickLayer +import net.fabricmc.loom.configuration.providers.mappings.utils.AddConstructorMappingVisitor import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider import net.fabricmc.loom.test.unit.LoomMocks import net.fabricmc.loom.util.download.Download @@ -109,7 +110,8 @@ abstract class LayeredMappingsSpecification extends Specification implements Lay def reorderedMappings = new MemoryMappingTree() def nsReorder = new MappingDstNsReorder(reorderedMappings, Collections.singletonList(MappingsNamespace.NAMED.toString())) def nsSwitch = new MappingSourceNsSwitch(nsReorder, MappingsNamespace.INTERMEDIARY.toString(), true) - mappingTree.accept(nsSwitch) + def addConstructor = new AddConstructorMappingVisitor(nsSwitch) + mappingTree.accept(addConstructor) return reorderedMappings } diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/ParchmentMappingLayerTest.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/ParchmentMappingLayerTest.groovy index 52720c38..ff2dfa1b 100644 --- a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/ParchmentMappingLayerTest.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/ParchmentMappingLayerTest.groovy @@ -51,6 +51,7 @@ class ParchmentMappingLayerTest extends LayeredMappingsSpecification { mappings.classes[0].getDstName(0) == "net/minecraft/class_2573" mappings.classes[0].methods[0].args[0].srcName.hashCode() == -1008297992 reorderedMappings.getClass("net/minecraft/class_2573").getMethod("method_10913", "(Lnet/minecraft/class_1799;Lnet/minecraft/class_1767;)V").args.size() > 0 + reorderedMappings.getClass("net/minecraft/class_2573").getMethod("", "()V") != null } def "Read parchment mappings remove prefix" () {