From d9a000670180e73569a6983c423dd4299278afda Mon Sep 17 00:00:00 2001 From: Josiah Glosson Date: Tue, 9 Jul 2024 15:53:31 -0500 Subject: [PATCH] Fix AWs not being applied when remapping in dev (#910) * Fix AWs not being applied when remapping in dev * Optimize imports * Review feedback --------- Co-authored-by: modmuss50 --- .../impl/discovery/RuntimeModRemapper.java | 90 ++++++++++++------- 1 file changed, 57 insertions(+), 33 deletions(-) diff --git a/src/main/java/net/fabricmc/loader/impl/discovery/RuntimeModRemapper.java b/src/main/java/net/fabricmc/loader/impl/discovery/RuntimeModRemapper.java index dd3ace119..3319f7405 100644 --- a/src/main/java/net/fabricmc/loader/impl/discovery/RuntimeModRemapper.java +++ b/src/main/java/net/fabricmc/loader/impl/discovery/RuntimeModRemapper.java @@ -39,9 +39,12 @@ import org.objectweb.asm.commons.Remapper; +import net.fabricmc.accesswidener.AccessWidener; +import net.fabricmc.accesswidener.AccessWidenerClassVisitor; import net.fabricmc.accesswidener.AccessWidenerReader; import net.fabricmc.accesswidener.AccessWidenerRemapper; import net.fabricmc.accesswidener.AccessWidenerWriter; +import net.fabricmc.loader.impl.FabricLoaderImpl; import net.fabricmc.loader.impl.FormattedException; import net.fabricmc.loader.impl.launch.FabricLauncher; import net.fabricmc.loader.impl.launch.FabricLauncherBase; @@ -60,6 +63,7 @@ public final class RuntimeModRemapper { private static final String REMAP_TYPE_MANIFEST_KEY = "Fabric-Loom-Mixin-Remap-Type"; private static final String REMAP_TYPE_STATIC = "static"; + private static final String SOURCE_NAMESPACE = "intermediary"; public static void remap(Collection modCandidates, Path tmpDir, Path outputDir) { List modsToRemap = new ArrayList<>(); @@ -73,30 +77,20 @@ public static void remap(Collection modCandidates, Path tmpDir, Pa if (modsToRemap.isEmpty()) return; - FabricLauncher launcher = FabricLauncherBase.getLauncher(); + Map infoMap = new HashMap<>(); - TinyRemapper remapper = TinyRemapper.newRemapper() - .withMappings(TinyUtils.createMappingProvider(launcher.getMappingConfiguration().getMappings(), "intermediary", launcher.getTargetNamespace())) - .renameInvalidLocals(false) - .extension(new MixinExtension(remapMixins::contains)) - .build(); + TinyRemapper remapper = null; try { - remapper.readClassPathAsync(getRemapClasspath().toArray(new Path[0])); - } catch (IOException e) { - throw new RuntimeException("Failed to populate remap classpath", e); - } + FabricLauncher launcher = FabricLauncherBase.getLauncher(); - Map infoMap = new HashMap<>(); + AccessWidener mergedAccessWidener = new AccessWidener(); + mergedAccessWidener.visitHeader(SOURCE_NAMESPACE); - try { for (ModCandidate mod : modsToRemap) { RemapInfo info = new RemapInfo(); infoMap.put(mod, info); - InputTag tag = remapper.createInputTag(); - info.tag = tag; - if (mod.hasPath()) { List paths = mod.getPaths(); if (paths.size() != 1) throw new UnsupportedOperationException("multiple path for "+mod); @@ -107,13 +101,50 @@ public static void remap(Collection modCandidates, Path tmpDir, Pa info.inputIsTemp = true; } + info.outputPath = outputDir.resolve(mod.getDefaultFileName()); + Files.deleteIfExists(info.outputPath); + + String accessWidener = mod.getMetadata().getAccessWidener(); + + if (accessWidener != null) { + info.accessWidenerPath = accessWidener; + + try (FileSystemUtil.FileSystemDelegate jarFs = FileSystemUtil.getJarFileSystem(info.inputPath, false)) { + FileSystem fs = jarFs.get(); + info.accessWidener = Files.readAllBytes(fs.getPath(accessWidener)); + } catch (Throwable t) { + throw new RuntimeException("Error reading access widener for mod '" +mod.getId()+ "'!", t); + } + + new AccessWidenerReader(mergedAccessWidener).read(info.accessWidener); + } + } + + remapper = TinyRemapper.newRemapper() + .withMappings(TinyUtils.createMappingProvider(launcher.getMappingConfiguration().getMappings(), SOURCE_NAMESPACE, launcher.getTargetNamespace())) + .renameInvalidLocals(false) + .extension(new MixinExtension(remapMixins::contains)) + .extraAnalyzeVisitor((mrjVersion, className, next) -> + AccessWidenerClassVisitor.createClassVisitor(FabricLoaderImpl.ASM_VERSION, next, mergedAccessWidener) + ) + .build(); + + try { + remapper.readClassPathAsync(getRemapClasspath().toArray(new Path[0])); + } catch (IOException e) { + throw new RuntimeException("Failed to populate remap classpath", e); + } + + for (ModCandidate mod : modsToRemap) { + RemapInfo info = infoMap.get(mod); + + InputTag tag = remapper.createInputTag(); + info.tag = tag; + if (requiresMixinRemap(info.inputPath)) { remapMixins.add(tag); } - info.outputPath = outputDir.resolve(mod.getDefaultFileName()); - Files.deleteIfExists(info.outputPath); - remapper.readInputsAsync(tag, info.inputPath); } @@ -140,17 +171,8 @@ public static void remap(Collection modCandidates, Path tmpDir, Pa for (ModCandidate mod : modsToRemap) { RemapInfo info = infoMap.get(mod); - String accessWidener = mod.getMetadata().getAccessWidener(); - - if (accessWidener != null) { - info.accessWidenerPath = accessWidener; - - try (FileSystemUtil.FileSystemDelegate jarFs = FileSystemUtil.getJarFileSystem(info.inputPath, false)) { - FileSystem fs = jarFs.get(); - info.accessWidener = remapAccessWidener(Files.readAllBytes(fs.getPath(accessWidener)), remapper.getRemapper()); - } catch (Throwable t) { - throw new RuntimeException("Error remapping access widener for mod '"+mod.getId()+"'!", t); - } + if (info.accessWidener != null) { + info.accessWidener = remapAccessWidener(info.accessWidener, remapper.getRemapper(), launcher.getTargetNamespace()); } } @@ -173,7 +195,9 @@ public static void remap(Collection modCandidates, Path tmpDir, Pa mod.setPaths(Collections.singletonList(info.outputPath)); } } catch (Throwable t) { - remapper.finish(); + if (remapper != null) { + remapper.finish(); + } for (RemapInfo info : infoMap.values()) { if (info.outputPath == null) { @@ -199,11 +223,11 @@ public static void remap(Collection modCandidates, Path tmpDir, Pa } } - private static byte[] remapAccessWidener(byte[] input, Remapper remapper) { + private static byte[] remapAccessWidener(byte[] input, Remapper remapper, String targetNamespace) { AccessWidenerWriter writer = new AccessWidenerWriter(); - AccessWidenerRemapper remappingDecorator = new AccessWidenerRemapper(writer, remapper, "intermediary", "named"); + AccessWidenerRemapper remappingDecorator = new AccessWidenerRemapper(writer, remapper, SOURCE_NAMESPACE, targetNamespace); AccessWidenerReader accessWidenerReader = new AccessWidenerReader(remappingDecorator); - accessWidenerReader.read(input, "intermediary"); + accessWidenerReader.read(input, SOURCE_NAMESPACE); return writer.write(); }