Migrate fully to mapping-io + Add comments about transitive access widners to generated sources (#495)
* Add comments about transitive access widners to generated sources * Migrate fully to mapping io * Use release version of lorenz-tiny * Review comment
This commit is contained in:
		
							parent
							
								
									d48c74161e
								
							
						
					
					
						commit
						9d9be1b842
					
				
					 13 changed files with 294 additions and 175 deletions
				
			
		|  | @ -79,15 +79,12 @@ dependencies { | |||
| 
 | ||||
| 	// tinyfile management | ||||
| 	implementation ('net.fabricmc:tiny-remapper:0.5.0') | ||||
| 	implementation ('net.fabricmc:tiny-mappings-parser:0.3.0+build.17') | ||||
| 
 | ||||
| 	implementation 'net.fabricmc:access-widener:2.0.0' | ||||
| 	implementation 'net.fabricmc:mapping-io:0.2.1' | ||||
| 
 | ||||
| 	implementation ('net.fabricmc:lorenz-tiny:3.0.0') { | ||||
| 	implementation ('net.fabricmc:lorenz-tiny:4.0.0') { | ||||
| 		transitive = false | ||||
| 	} | ||||
| 	implementation ('org.cadixdev:lorenz-io-proguard:0.5.7') | ||||
| 
 | ||||
| 	// decompilers | ||||
| 	implementation ('net.fabricmc:fabric-fernflower:1.4.1') | ||||
|  |  | |||
|  | @ -25,6 +25,7 @@ | |||
| package net.fabricmc.loom; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.util.List; | ||||
| import java.util.Set; | ||||
| import java.util.function.Supplier; | ||||
| 
 | ||||
|  | @ -38,6 +39,7 @@ import org.gradle.api.file.ConfigurableFileCollection; | |||
| import net.fabricmc.loom.api.LoomGradleExtensionAPI; | ||||
| import net.fabricmc.loom.configuration.InstallerData; | ||||
| import net.fabricmc.loom.configuration.LoomDependencyManager; | ||||
| import net.fabricmc.loom.configuration.accesswidener.AccessWidenerFile; | ||||
| import net.fabricmc.loom.configuration.processors.JarProcessorManager; | ||||
| import net.fabricmc.loom.configuration.providers.MinecraftProviderImpl; | ||||
| import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; | ||||
|  | @ -103,4 +105,8 @@ public interface LoomGradleExtension extends LoomGradleExtensionAPI { | |||
| 
 | ||||
| 	@Override | ||||
| 	MixinExtension getMixin(); | ||||
| 
 | ||||
| 	List<AccessWidenerFile> getTransitiveAccessWideners(); | ||||
| 
 | ||||
| 	void addTransitiveAccessWideners(List<AccessWidenerFile> accessWidenerFiles); | ||||
| } | ||||
|  |  | |||
|  | @ -40,7 +40,6 @@ import net.fabricmc.loom.configuration.CompileConfiguration; | |||
| import net.fabricmc.loom.configuration.FabricApiExtension; | ||||
| import net.fabricmc.loom.configuration.MavenPublication; | ||||
| import net.fabricmc.loom.configuration.ide.IdeConfiguration; | ||||
| import net.fabricmc.loom.configuration.providers.mappings.MappingsCache; | ||||
| import net.fabricmc.loom.decompilers.DecompilerConfiguration; | ||||
| import net.fabricmc.loom.extension.LoomFiles; | ||||
| import net.fabricmc.loom.extension.LoomGradleExtensionImpl; | ||||
|  | @ -68,7 +67,6 @@ public class LoomGradlePlugin implements BootstrappedPlugin { | |||
| 		refreshDeps = project.getGradle().getStartParameter().isRefreshDependencies(); | ||||
| 
 | ||||
| 		if (refreshDeps) { | ||||
| 			MappingsCache.INSTANCE.invalidate(); | ||||
| 			project.getLogger().lifecycle("Refresh dependencies is in use, loom will be significantly slower."); | ||||
| 		} | ||||
| 
 | ||||
|  |  | |||
|  | @ -60,6 +60,8 @@ public class TransitiveAccessWidenerJarProcessor implements JarProcessor { | |||
| 		this.extension = LoomGradleExtension.get(project); | ||||
| 
 | ||||
| 		transitiveAccessWideners = getTransitiveAccessWideners(); | ||||
| 
 | ||||
| 		extension.addTransitiveAccessWideners(transitiveAccessWideners); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
|  |  | |||
|  | @ -0,0 +1,147 @@ | |||
| /* | ||||
|  * 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.accesswidener; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.io.Reader; | ||||
| import java.io.Writer; | ||||
| import java.nio.charset.StandardCharsets; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import org.gradle.api.logging.Logger; | ||||
| 
 | ||||
| import net.fabricmc.accesswidener.AccessWidenerReader; | ||||
| import net.fabricmc.accesswidener.AccessWidenerVisitor; | ||||
| import net.fabricmc.accesswidener.TransitiveOnlyFilter; | ||||
| import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; | ||||
| import net.fabricmc.mappingio.MappingReader; | ||||
| import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch; | ||||
| import net.fabricmc.mappingio.format.Tiny2Writer; | ||||
| import net.fabricmc.mappingio.tree.MappingTree; | ||||
| import net.fabricmc.mappingio.tree.MemoryMappingTree; | ||||
| 
 | ||||
| public final class TransitiveAccessWidenerMappingsProcessor { | ||||
| 	private TransitiveAccessWidenerMappingsProcessor() { | ||||
| 	} | ||||
| 
 | ||||
| 	public static void process(Path inputMappings, Path outputMappings, List<AccessWidenerFile> accessWideners, Logger logger) { | ||||
| 		MemoryMappingTree mappingTree = new MemoryMappingTree(); | ||||
| 
 | ||||
| 		try (Reader reader = Files.newBufferedReader(inputMappings, StandardCharsets.UTF_8)) { | ||||
| 			MappingReader.read(reader, new MappingSourceNsSwitch(mappingTree, MappingsNamespace.INTERMEDIARY.toString())); | ||||
| 		} catch (IOException e) { | ||||
| 			throw new RuntimeException("Failed to read mappings", e); | ||||
| 		} | ||||
| 
 | ||||
| 		if (!MappingsNamespace.INTERMEDIARY.toString().equals(mappingTree.getSrcNamespace())) { | ||||
| 			throw new IllegalStateException("Mapping tree must have intermediary src mappings not " + mappingTree.getSrcNamespace()); | ||||
| 		} | ||||
| 
 | ||||
| 		for (AccessWidenerFile accessWidener : accessWideners) { | ||||
| 			MappingCommentVisitor mappingCommentVisitor = new MappingCommentVisitor(accessWidener.modId(), mappingTree, logger); | ||||
| 			AccessWidenerReader accessWidenerReader = new AccessWidenerReader(new TransitiveOnlyFilter(mappingCommentVisitor)); | ||||
| 			accessWidenerReader.read(accessWidener.content()); | ||||
| 		} | ||||
| 
 | ||||
| 		try (Writer writer = Files.newBufferedWriter(outputMappings, StandardCharsets.UTF_8)) { | ||||
| 			Tiny2Writer tiny2Writer = new Tiny2Writer(writer, false); | ||||
| 			mappingTree.accept(new MappingSourceNsSwitch(tiny2Writer, MappingsNamespace.NAMED.toString())); | ||||
| 		} catch (IOException e) { | ||||
| 			throw new RuntimeException("Failed to write mappings", e); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	private static record MappingCommentVisitor(String modId, MemoryMappingTree mappingTree, Logger logger) implements AccessWidenerVisitor { | ||||
| 		@Override | ||||
| 		public void visitClass(String name, AccessWidenerReader.AccessType access, boolean transitive) { | ||||
| 			MappingTree.ClassMapping classMapping = mappingTree.getClass(name); | ||||
| 
 | ||||
| 			if (classMapping == null) { | ||||
| 				logger.warn("Failed to find class ({}) to mark access widened by mod ({})", name, modId()); | ||||
| 				return; | ||||
| 			} | ||||
| 
 | ||||
| 			classMapping.setComment(appendComment(classMapping.getComment(), access)); | ||||
| 		} | ||||
| 
 | ||||
| 		@Override | ||||
| 		public void visitMethod(String owner, String name, String descriptor, AccessWidenerReader.AccessType access, boolean transitive) { | ||||
| 			// Access is also applied to the class, so also add the comment to the class | ||||
| 			visitClass(owner, access, transitive); | ||||
| 
 | ||||
| 			MappingTree.ClassMapping classMapping = mappingTree.getClass(owner); | ||||
| 
 | ||||
| 			if (classMapping == null) { | ||||
| 				logger.warn("Failed to find class ({}) to mark access widened by mod ({})", owner, modId()); | ||||
| 				return; | ||||
| 			} | ||||
| 
 | ||||
| 			MappingTree.MethodMapping methodMapping = classMapping.getMethod(name, descriptor); | ||||
| 
 | ||||
| 			if (methodMapping == null) { | ||||
| 				logger.warn("Failed to find method ({}) in ({}) to mark access widened by mod ({})", name, owner, modId()); | ||||
| 				return; | ||||
| 			} | ||||
| 
 | ||||
| 			methodMapping.setComment(appendComment(methodMapping.getComment(), access)); | ||||
| 		} | ||||
| 
 | ||||
| 		@Override | ||||
| 		public void visitField(String owner, String name, String descriptor, AccessWidenerReader.AccessType access, boolean transitive) { | ||||
| 			// Access is also applied to the class, so also add the comment to the class | ||||
| 			visitClass(owner, access, transitive); | ||||
| 
 | ||||
| 			MappingTree.ClassMapping classMapping = mappingTree.getClass(owner); | ||||
| 
 | ||||
| 			if (classMapping == null) { | ||||
| 				logger.warn("Failed to find class ({}) to mark access widened by mod ({})", name, modId()); | ||||
| 				return; | ||||
| 			} | ||||
| 
 | ||||
| 			MappingTree.FieldMapping fieldMapping = classMapping.getField(name, descriptor); | ||||
| 
 | ||||
| 			if (fieldMapping == null) { | ||||
| 				logger.warn("Failed to find field ({}) in ({}) to mark access widened by mod ({})", name, owner, modId()); | ||||
| 				return; | ||||
| 			} | ||||
| 
 | ||||
| 			fieldMapping.setComment(appendComment(fieldMapping.getComment(), access)); | ||||
| 		} | ||||
| 
 | ||||
| 		private String appendComment(String comment, AccessWidenerReader.AccessType access) { | ||||
| 			if (comment == null) { | ||||
| 				comment = ""; | ||||
| 			} else { | ||||
| 				comment += "\n"; | ||||
| 			} | ||||
| 
 | ||||
| 			comment += "Access widened by %s to %s".formatted(modId(), access); | ||||
| 
 | ||||
| 			return comment; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | @ -1,69 +0,0 @@ | |||
| /* | ||||
|  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||
|  * | ||||
|  * Copyright (c) 2016-2020 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; | ||||
| 
 | ||||
| import java.io.BufferedReader; | ||||
| import java.io.IOException; | ||||
| import java.lang.ref.SoftReference; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| import net.fabricmc.loom.util.StaticPathWatcher; | ||||
| import net.fabricmc.mapping.tree.TinyMappingFactory; | ||||
| import net.fabricmc.mapping.tree.TinyTree; | ||||
| 
 | ||||
| public final class MappingsCache { | ||||
| 	public static final MappingsCache INSTANCE = new MappingsCache(); | ||||
| 
 | ||||
| 	private final Map<Path, SoftReference<TinyTree>> mappingsCache = new HashMap<>(); | ||||
| 
 | ||||
| 	// TODO: loom doesn't actually use new mappings when the mappings change until the gradle daemons are stopped | ||||
| 	public TinyTree get(Path mappingsPath) throws IOException { | ||||
| 		mappingsPath = mappingsPath.toAbsolutePath(); | ||||
| 
 | ||||
| 		if (StaticPathWatcher.INSTANCE.hasFileChanged(mappingsPath)) { | ||||
| 			mappingsCache.remove(mappingsPath); | ||||
| 		} | ||||
| 
 | ||||
| 		SoftReference<TinyTree> ref = mappingsCache.get(mappingsPath); | ||||
| 
 | ||||
| 		if (ref != null && ref.get() != null) { | ||||
| 			return ref.get(); | ||||
| 		} else { | ||||
| 			try (BufferedReader reader = Files.newBufferedReader(mappingsPath)) { | ||||
| 				TinyTree mappings = TinyMappingFactory.loadWithDetection(reader); | ||||
| 				ref = new SoftReference<>(mappings); | ||||
| 				mappingsCache.put(mappingsPath, ref); | ||||
| 				return mappings; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public void invalidate() { | ||||
| 		mappingsCache.clear(); | ||||
| 	} | ||||
| } | ||||
|  | @ -35,6 +35,7 @@ import java.nio.file.Files; | |||
| import java.nio.file.Path; | ||||
| import java.nio.file.StandardCopyOption; | ||||
| import java.util.Collections; | ||||
| import java.util.Objects; | ||||
| import java.util.function.Consumer; | ||||
| 
 | ||||
| import com.google.common.base.Stopwatch; | ||||
|  | @ -59,10 +60,10 @@ import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvid | |||
| import net.fabricmc.loom.util.Constants; | ||||
| import net.fabricmc.loom.util.DeletingFileVisitor; | ||||
| import net.fabricmc.loom.util.DownloadUtil; | ||||
| import net.fabricmc.mapping.reader.v2.TinyV2Factory; | ||||
| import net.fabricmc.mapping.tree.TinyTree; | ||||
| import net.fabricmc.mappingio.MappingReader; | ||||
| import net.fabricmc.mappingio.adapter.MappingNsCompleter; | ||||
| import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch; | ||||
| import net.fabricmc.mappingio.format.MappingFormat; | ||||
| import net.fabricmc.mappingio.format.Tiny2Reader; | ||||
| import net.fabricmc.mappingio.format.Tiny2Writer; | ||||
| import net.fabricmc.mappingio.tree.MemoryMappingTree; | ||||
|  | @ -87,13 +88,14 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings | |||
| 	private Path unpickDefinitions; | ||||
| 	private boolean hasUnpickDefinitions; | ||||
| 	private UnpickMetadata unpickMetadata; | ||||
| 	private MemoryMappingTree mappingTree; | ||||
| 
 | ||||
| 	public MappingsProviderImpl(Project project) { | ||||
| 		super(project); | ||||
| 	} | ||||
| 
 | ||||
| 	public TinyTree getMappings() throws IOException { | ||||
| 		return MappingsCache.INSTANCE.get(tinyMappings); | ||||
| 	public MemoryMappingTree getMappings() throws IOException { | ||||
| 		return Objects.requireNonNull(mappingTree, "Cannot get mappings before they have been read"); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
|  | @ -119,6 +121,8 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings | |||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		mappingTree = readMappings(); | ||||
| 
 | ||||
| 		if (Files.notExists(tinyMappingsJar) || isRefreshDeps()) { | ||||
| 			ZipUtil.pack(new ZipEntrySource[] {new FileSource("mappings/mappings.tiny", tinyMappings.toFile())}, tinyMappingsJar.toFile()); | ||||
| 		} | ||||
|  | @ -216,23 +220,22 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	private MemoryMappingTree readMappings() throws IOException { | ||||
| 		MemoryMappingTree mappingTree = new MemoryMappingTree(); | ||||
| 		MappingReader.read(tinyMappings, mappingTree); | ||||
| 		return mappingTree; | ||||
| 	} | ||||
| 
 | ||||
| 	private static boolean areMappingsV2(Path path) throws IOException { | ||||
| 		try (BufferedReader reader = Files.newBufferedReader(path)) { | ||||
| 			TinyV2Factory.readMetadata(reader); | ||||
| 			return true; | ||||
| 		} catch (IllegalArgumentException e) { | ||||
| 			// TODO: just check the mappings version when Parser supports V1 in readMetadata() | ||||
| 			return false; | ||||
| 			return MappingReader.detectFormat(reader) == MappingFormat.TINY_2; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	private static boolean doesJarContainV2Mappings(Path path) throws IOException { | ||||
| 		try (FileSystem fs = FileSystems.newFileSystem(path, (ClassLoader) null)) { | ||||
| 			try (BufferedReader reader = Files.newBufferedReader(fs.getPath("mappings", "mappings.tiny"))) { | ||||
| 				TinyV2Factory.readMetadata(reader); | ||||
| 				return true; | ||||
| 			} catch (IllegalArgumentException e) { | ||||
| 				return false; | ||||
| 				return MappingReader.detectFormat(reader) == MappingFormat.TINY_2; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  |  | |||
|  | @ -29,9 +29,7 @@ import java.io.File; | |||
| import java.io.IOException; | ||||
| import java.nio.file.Files; | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| import org.jetbrains.java.decompiler.struct.StructClass; | ||||
| import org.jetbrains.java.decompiler.struct.StructField; | ||||
|  | @ -40,48 +38,29 @@ import org.jetbrains.java.decompiler.struct.StructRecordComponent; | |||
| import org.objectweb.asm.Opcodes; | ||||
| 
 | ||||
| import net.fabricmc.fernflower.api.IFabricJavadocProvider; | ||||
| import net.fabricmc.mapping.tree.ClassDef; | ||||
| import net.fabricmc.mapping.tree.FieldDef; | ||||
| import net.fabricmc.mapping.tree.MethodDef; | ||||
| import net.fabricmc.mapping.tree.ParameterDef; | ||||
| import net.fabricmc.mapping.tree.TinyMappingFactory; | ||||
| import net.fabricmc.mapping.tree.TinyTree; | ||||
| import net.fabricmc.mappings.EntryTriple; | ||||
| import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; | ||||
| import net.fabricmc.mappingio.MappingReader; | ||||
| import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch; | ||||
| import net.fabricmc.mappingio.tree.MappingTree; | ||||
| import net.fabricmc.mappingio.tree.MemoryMappingTree; | ||||
| 
 | ||||
| public class TinyJavadocProvider implements IFabricJavadocProvider { | ||||
| 	private final Map<String, ClassDef> classes = new HashMap<>(); | ||||
| 	private final Map<EntryTriple, FieldDef> fields = new HashMap<>(); | ||||
| 	private final Map<EntryTriple, MethodDef> methods = new HashMap<>(); | ||||
| 
 | ||||
| 	private final String namespace = "named"; | ||||
| 	private final MappingTree mappingTree; | ||||
| 
 | ||||
| 	public TinyJavadocProvider(File tinyFile) { | ||||
| 		final TinyTree mappings = readMappings(tinyFile); | ||||
| 
 | ||||
| 		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)), methodDef); | ||||
| 			} | ||||
| 		} | ||||
| 		mappingTree = readMappings(tinyFile); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public String getClassDoc(StructClass structClass) { | ||||
| 		ClassDef classDef = classes.get(structClass.qualifiedName); | ||||
| 		MappingTree.ClassMapping classMapping = mappingTree.getClass(structClass.qualifiedName); | ||||
| 
 | ||||
| 		if (classDef == null) { | ||||
| 		if (classMapping == null) { | ||||
| 			return null; | ||||
| 		} | ||||
| 
 | ||||
| 		if (!isRecord(structClass)) { | ||||
| 			return classDef.getComment(); | ||||
| 			return classMapping.getComment(); | ||||
| 		} | ||||
| 
 | ||||
| 		/** | ||||
|  | @ -91,30 +70,30 @@ public class TinyJavadocProvider implements IFabricJavadocProvider { | |||
| 		 */ | ||||
| 		List<String> parts = new ArrayList<>(); | ||||
| 
 | ||||
| 		if (classDef.getComment() != null) { | ||||
| 			parts.add(classDef.getComment()); | ||||
| 		if (classMapping.getComment() != null) { | ||||
| 			parts.add(classMapping.getComment()); | ||||
| 		} | ||||
| 
 | ||||
| 		boolean addedParam = false; | ||||
| 
 | ||||
| 		for (StructRecordComponent component : structClass.getRecordComponents()) { | ||||
| 			// The component will always match the field name and descriptor | ||||
| 			FieldDef fieldDef = fields.get(new EntryTriple(structClass.qualifiedName, component.getName(), component.getDescriptor())); | ||||
| 			MappingTree.FieldMapping fieldMapping = classMapping.getField(component.getName(), component.getDescriptor()); | ||||
| 
 | ||||
| 			if (fieldDef == null) { | ||||
| 			if (fieldMapping == null) { | ||||
| 				continue; | ||||
| 			} | ||||
| 
 | ||||
| 			String comment = fieldDef.getComment(); | ||||
| 			String comment = fieldMapping.getComment(); | ||||
| 
 | ||||
| 			if (comment != null) { | ||||
| 				if (!addedParam && classDef.getComment() != null) { | ||||
| 				if (!addedParam && classMapping.getComment() != null) { | ||||
| 					//Add a blank line before components when the class has a comment | ||||
| 					parts.add(""); | ||||
| 					addedParam = true; | ||||
| 				} | ||||
| 
 | ||||
| 				parts.add(String.format("@param %s %s", fieldDef.getName(namespace), comment)); | ||||
| 				parts.add(String.format("@param %s %s", fieldMapping.getName(MappingsNamespace.NAMED.toString()), comment)); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
|  | @ -132,34 +111,47 @@ public class TinyJavadocProvider implements IFabricJavadocProvider { | |||
| 			return null; | ||||
| 		} | ||||
| 
 | ||||
| 		FieldDef fieldDef = fields.get(new EntryTriple(structClass.qualifiedName, structField.getName(), structField.getDescriptor())); | ||||
| 		return fieldDef != null ? fieldDef.getComment() : null; | ||||
| 		MappingTree.ClassMapping classMapping = mappingTree.getClass(structClass.qualifiedName); | ||||
| 
 | ||||
| 		if (classMapping == null) { | ||||
| 			return null; | ||||
| 		} | ||||
| 
 | ||||
| 		MappingTree.FieldMapping fieldMapping = classMapping.getField(structField.getName(), structField.getDescriptor()); | ||||
| 
 | ||||
| 		return fieldMapping != null ? fieldMapping.getComment() : null; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public String getMethodDoc(StructClass structClass, StructMethod structMethod) { | ||||
| 		MethodDef methodDef = methods.get(new EntryTriple(structClass.qualifiedName, structMethod.getName(), structMethod.getDescriptor())); | ||||
| 		MappingTree.ClassMapping classMapping = mappingTree.getClass(structClass.qualifiedName); | ||||
| 
 | ||||
| 		if (methodDef != null) { | ||||
| 		if (classMapping == null) { | ||||
| 			return null; | ||||
| 		} | ||||
| 
 | ||||
| 		MappingTree.MethodMapping methodMapping = classMapping.getMethod(structMethod.getName(), structMethod.getDescriptor()); | ||||
| 
 | ||||
| 		if (methodMapping != null) { | ||||
| 			List<String> parts = new ArrayList<>(); | ||||
| 
 | ||||
| 			if (methodDef.getComment() != null) { | ||||
| 				parts.add(methodDef.getComment()); | ||||
| 			if (methodMapping.getComment() != null) { | ||||
| 				parts.add(methodMapping.getComment()); | ||||
| 			} | ||||
| 
 | ||||
| 			boolean addedParam = false; | ||||
| 
 | ||||
| 			for (ParameterDef param : methodDef.getParameters()) { | ||||
| 				String comment = param.getComment(); | ||||
| 			for (MappingTree.MethodArgMapping argMapping : methodMapping.getArgs()) { | ||||
| 				String comment = argMapping.getComment(); | ||||
| 
 | ||||
| 				if (comment != null) { | ||||
| 					if (!addedParam && methodDef.getComment() != null) { | ||||
| 					if (!addedParam && methodMapping.getComment() != null) { | ||||
| 						//Add a blank line before params when the method has a comment | ||||
| 						parts.add(""); | ||||
| 						addedParam = true; | ||||
| 					} | ||||
| 
 | ||||
| 					parts.add(String.format("@param %s %s", param.getName(namespace), comment)); | ||||
| 					parts.add(String.format("@param %s %s", methodMapping.getName(MappingsNamespace.NAMED.toString()), comment)); | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
|  | @ -173,9 +165,13 @@ public class TinyJavadocProvider implements IFabricJavadocProvider { | |||
| 		return null; | ||||
| 	} | ||||
| 
 | ||||
| 	private static TinyTree readMappings(File input) { | ||||
| 	private static MappingTree readMappings(File input) { | ||||
| 		try (BufferedReader reader = Files.newBufferedReader(input.toPath())) { | ||||
| 			return TinyMappingFactory.loadWithDetection(reader); | ||||
| 			MemoryMappingTree mappingTree = new MemoryMappingTree(); | ||||
| 			MappingSourceNsSwitch nsSwitch = new MappingSourceNsSwitch(mappingTree, MappingsNamespace.NAMED.toString()); | ||||
| 			MappingReader.read(reader, nsSwitch); | ||||
| 
 | ||||
| 			return mappingTree; | ||||
| 		} catch (IOException e) { | ||||
| 			throw new RuntimeException("Failed to read mappings", e); | ||||
| 		} | ||||
|  |  | |||
|  | @ -25,9 +25,11 @@ | |||
| package net.fabricmc.loom.extension; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collections; | ||||
| import java.util.HashMap; | ||||
| import java.util.HashSet; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.Objects; | ||||
| import java.util.Set; | ||||
|  | @ -43,6 +45,7 @@ import org.gradle.api.file.ConfigurableFileCollection; | |||
| import net.fabricmc.loom.LoomGradleExtension; | ||||
| import net.fabricmc.loom.configuration.InstallerData; | ||||
| import net.fabricmc.loom.configuration.LoomDependencyManager; | ||||
| import net.fabricmc.loom.configuration.accesswidener.AccessWidenerFile; | ||||
| import net.fabricmc.loom.configuration.processors.JarProcessorManager; | ||||
| 
 | ||||
| public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implements LoomGradleExtension { | ||||
|  | @ -55,6 +58,7 @@ public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implemen | |||
| 	private final MappingSet[] srcMappingCache = new MappingSet[2]; | ||||
| 	private final Mercury[] srcMercuryCache = new Mercury[2]; | ||||
| 	private final Map<String, NamedDomainObjectProvider<Configuration>> lazyConfigurations = new HashMap<>(); | ||||
| 	private final List<AccessWidenerFile> transitiveAccessWideners = new ArrayList<>(); | ||||
| 
 | ||||
| 	private LoomDependencyManager dependencyManager; | ||||
| 	private JarProcessorManager jarProcessorManager; | ||||
|  | @ -168,4 +172,14 @@ public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implemen | |||
| 	public MixinExtension getMixin() { | ||||
| 		return this.mixinApExtension; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public List<AccessWidenerFile> getTransitiveAccessWideners() { | ||||
| 		return transitiveAccessWideners; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public void addTransitiveAccessWideners(List<AccessWidenerFile> accessWidenerFiles) { | ||||
| 		transitiveAccessWideners.addAll(accessWidenerFiles); | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -30,6 +30,7 @@ import java.nio.file.Files; | |||
| import java.nio.file.Path; | ||||
| import java.nio.file.StandardCopyOption; | ||||
| import java.util.Collection; | ||||
| import java.util.List; | ||||
| import java.util.Locale; | ||||
| import java.util.stream.Collectors; | ||||
| 
 | ||||
|  | @ -41,6 +42,8 @@ import org.gradle.api.tasks.TaskAction; | |||
| import net.fabricmc.loom.LoomGradleExtension; | ||||
| import net.fabricmc.loom.api.decompilers.DecompilationMetadata; | ||||
| import net.fabricmc.loom.api.decompilers.LoomDecompiler; | ||||
| import net.fabricmc.loom.configuration.accesswidener.AccessWidenerFile; | ||||
| import net.fabricmc.loom.configuration.accesswidener.TransitiveAccessWidenerMappingsProcessor; | ||||
| import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; | ||||
| import net.fabricmc.loom.decompilers.LineNumberRemapper; | ||||
| import net.fabricmc.loom.util.Constants; | ||||
|  | @ -62,11 +65,10 @@ public class GenerateSourcesTask extends AbstractLoomTask { | |||
| 	@TaskAction | ||||
| 	public void doTask() throws Throwable { | ||||
| 		int threads = Runtime.getRuntime().availableProcessors(); | ||||
| 		Path javaDocs = getExtension().getMappingsProvider().tinyMappings; | ||||
| 		Collection<Path> libraries = getProject().getConfigurations().getByName(Constants.Configurations.MINECRAFT_DEPENDENCIES).getFiles() | ||||
| 						.stream().map(File::toPath).collect(Collectors.toSet()); | ||||
| 				.stream().map(File::toPath).collect(Collectors.toSet()); | ||||
| 
 | ||||
| 		DecompilationMetadata metadata = new DecompilationMetadata(threads, javaDocs, libraries); | ||||
| 		DecompilationMetadata metadata = new DecompilationMetadata(threads, getMappings(), libraries); | ||||
| 		Path runtimeJar = getExtension().getMappingsProvider().mappedProvider.getMappedJar().toPath(); | ||||
| 		Path sourcesDestination = getMappedJarFileWithSuffix("-sources.jar").toPath(); | ||||
| 		Path linemap = getMappedJarFileWithSuffix("-sources.lmap").toPath(); | ||||
|  | @ -92,7 +94,7 @@ public class GenerateSourcesTask extends AbstractLoomTask { | |||
| 		progressLogger.start("Adjusting line numbers", "linemap"); | ||||
| 
 | ||||
| 		try (StitchUtil.FileSystemDelegate inFs = StitchUtil.getJarFileSystem(oldCompiledJar.toFile(), true); | ||||
| 			StitchUtil.FileSystemDelegate outFs = StitchUtil.getJarFileSystem(linemappedJarDestination.toFile(), true)) { | ||||
| 				StitchUtil.FileSystemDelegate outFs = StitchUtil.getJarFileSystem(linemappedJarDestination.toFile(), true)) { | ||||
| 			remapper.process(progressLogger, inFs.get().getPath("/"), outFs.get().getPath("/")); | ||||
| 		} | ||||
| 
 | ||||
|  | @ -112,6 +114,32 @@ public class GenerateSourcesTask extends AbstractLoomTask { | |||
| 		return new File(path.substring(0, path.length() - 4) + suffix); | ||||
| 	} | ||||
| 
 | ||||
| 	private Path getMappings() { | ||||
| 		Path baseMappings = getExtension().getMappingsProvider().tinyMappings; | ||||
| 
 | ||||
| 		if (getExtension().getEnableTransitiveAccessWideners().get()) { | ||||
| 			List<AccessWidenerFile> accessWideners = getExtension().getTransitiveAccessWideners(); | ||||
| 
 | ||||
| 			if (accessWideners.isEmpty()) { | ||||
| 				return baseMappings; | ||||
| 			} | ||||
| 
 | ||||
| 			Path outputMappings; | ||||
| 
 | ||||
| 			try { | ||||
| 				outputMappings = Files.createTempFile("loom-transitive-mappings", ".tiny"); | ||||
| 			} catch (IOException e) { | ||||
| 				throw new RuntimeException("Failed to create temp file", e); | ||||
| 			} | ||||
| 
 | ||||
| 			TransitiveAccessWidenerMappingsProcessor.process(baseMappings, outputMappings, accessWideners, getProject().getLogger()); | ||||
| 
 | ||||
| 			return outputMappings; | ||||
| 		} | ||||
| 
 | ||||
| 		return baseMappings; | ||||
| 	} | ||||
| 
 | ||||
| 	@InputFile | ||||
| 	public File getInputJar() { | ||||
| 		return inputJar; | ||||
|  |  | |||
|  | @ -24,14 +24,12 @@ | |||
| 
 | ||||
| package net.fabricmc.loom.task; | ||||
| 
 | ||||
| import java.io.BufferedReader; | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.nio.file.FileSystem; | ||||
| import java.nio.file.FileSystems; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
| import java.nio.file.StandardCopyOption; | ||||
| import java.util.Set; | ||||
| 
 | ||||
| import com.google.common.collect.ImmutableMap; | ||||
|  | @ -49,15 +47,15 @@ import org.gradle.api.tasks.TaskAction; | |||
| import org.gradle.api.tasks.options.Option; | ||||
| 
 | ||||
| import net.fabricmc.loom.LoomGradleExtension; | ||||
| import net.fabricmc.loom.api.mappings.layered.spec.LayeredMappingSpecBuilder; | ||||
| import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; | ||||
| import net.fabricmc.loom.api.mappings.layered.spec.LayeredMappingSpecBuilder; | ||||
| import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingsDependency; | ||||
| import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; | ||||
| import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvider; | ||||
| import net.fabricmc.loom.util.SourceRemapper; | ||||
| import net.fabricmc.lorenztiny.TinyMappingsJoiner; | ||||
| import net.fabricmc.mapping.tree.TinyMappingFactory; | ||||
| import net.fabricmc.mapping.tree.TinyTree; | ||||
| import net.fabricmc.mappingio.MappingReader; | ||||
| import net.fabricmc.mappingio.tree.MemoryMappingTree; | ||||
| 
 | ||||
| public class MigrateMappingsTask extends AbstractLoomTask { | ||||
| 	private Path inputDir; | ||||
|  | @ -101,8 +99,8 @@ public class MigrateMappingsTask extends AbstractLoomTask { | |||
| 		MappingsProviderImpl mappingsProvider = extension.getMappingsProvider(); | ||||
| 
 | ||||
| 		try { | ||||
| 			TinyTree currentMappings = mappingsProvider.getMappings(); | ||||
| 			TinyTree targetMappings = getMappings(mappings); | ||||
| 			MemoryMappingTree currentMappings = mappingsProvider.getMappings(); | ||||
| 			MemoryMappingTree targetMappings = getMappings(mappings); | ||||
| 			migrateMappings(project, extension.getMinecraftMappedProvider(), inputDir, outputDir, currentMappings, targetMappings); | ||||
| 			project.getLogger().lifecycle(":remapped project written to " + outputDir.toAbsolutePath()); | ||||
| 		} catch (IOException e) { | ||||
|  | @ -149,20 +147,18 @@ public class MigrateMappingsTask extends AbstractLoomTask { | |||
| 		return Iterables.getOnlyElement(files); | ||||
| 	} | ||||
| 
 | ||||
| 	private static TinyTree getMappings(File mappings) throws IOException { | ||||
| 		Path temp = Files.createTempFile("mappings", ".tiny"); | ||||
| 	private static MemoryMappingTree getMappings(File mappings) throws IOException { | ||||
| 		MemoryMappingTree mappingTree = new MemoryMappingTree(); | ||||
| 
 | ||||
| 		try (FileSystem fileSystem = FileSystems.newFileSystem(mappings.toPath(), (ClassLoader) null)) { | ||||
| 			Files.copy(fileSystem.getPath("mappings/mappings.tiny"), temp, StandardCopyOption.REPLACE_EXISTING); | ||||
| 			MappingReader.read(fileSystem.getPath("mappings/mappings.tiny"), mappingTree); | ||||
| 		} | ||||
| 
 | ||||
| 		try (BufferedReader reader = Files.newBufferedReader(temp)) { | ||||
| 			return TinyMappingFactory.loadWithDetection(reader); | ||||
| 		} | ||||
| 		return mappingTree; | ||||
| 	} | ||||
| 
 | ||||
| 	private static void migrateMappings(Project project, MinecraftMappedProvider minecraftMappedProvider, | ||||
| 										Path inputDir, Path outputDir, TinyTree currentMappings, TinyTree targetMappings | ||||
| 										Path inputDir, Path outputDir, MemoryMappingTree currentMappings, MemoryMappingTree targetMappings | ||||
| 	) throws IOException { | ||||
| 		project.getLogger().info(":joining mappings"); | ||||
| 
 | ||||
|  |  | |||
|  | @ -45,7 +45,7 @@ import net.fabricmc.loom.configuration.RemappedConfigurationEntry; | |||
| import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; | ||||
| import net.fabricmc.loom.util.gradle.ProgressLogger; | ||||
| import net.fabricmc.lorenztiny.TinyMappingsReader; | ||||
| import net.fabricmc.mapping.tree.TinyTree; | ||||
| import net.fabricmc.mappingio.tree.MemoryMappingTree; | ||||
| import net.fabricmc.stitch.util.StitchUtil; | ||||
| 
 | ||||
| public class SourceRemapper { | ||||
|  | @ -165,7 +165,7 @@ public class SourceRemapper { | |||
| 
 | ||||
| 		MappingSet mappings = extension.getOrCreateSrcMappingCache(toNamed ? 1 : 0, () -> { | ||||
| 			try { | ||||
| 				TinyTree m = mappingsProvider.getMappings(); | ||||
| 				MemoryMappingTree m = mappingsProvider.getMappings(); | ||||
| 				project.getLogger().info(":loading " + (toNamed ? "intermediary -> named" : "named -> intermediary") + " source mappings"); | ||||
| 				return new TinyMappingsReader(m, toNamed ? MappingsNamespace.INTERMEDIARY.toString() : MappingsNamespace.NAMED.toString(), toNamed ? MappingsNamespace.NAMED.toString() : MappingsNamespace.INTERMEDIARY.toString()).read(); | ||||
| 			} catch (Exception e) { | ||||
|  |  | |||
|  | @ -33,12 +33,7 @@ import com.google.common.collect.ImmutableMap; | |||
| import org.gradle.api.Project; | ||||
| 
 | ||||
| import net.fabricmc.loom.LoomGradleExtension; | ||||
| import net.fabricmc.mapping.tree.ClassDef; | ||||
| import net.fabricmc.mapping.tree.FieldDef; | ||||
| import net.fabricmc.mapping.tree.LocalVariableDef; | ||||
| import net.fabricmc.mapping.tree.MethodDef; | ||||
| import net.fabricmc.mapping.tree.ParameterDef; | ||||
| import net.fabricmc.mapping.tree.TinyTree; | ||||
| import net.fabricmc.mappingio.tree.MappingTree; | ||||
| import net.fabricmc.tinyremapper.IMappingProvider; | ||||
| import net.fabricmc.tinyremapper.TinyRemapper; | ||||
| 
 | ||||
|  | @ -75,28 +70,34 @@ public final class TinyRemapperHelper { | |||
| 		return new IMappingProvider.Member(className, memberName, descriptor); | ||||
| 	} | ||||
| 
 | ||||
| 	public static IMappingProvider create(TinyTree mappings, String from, String to, boolean remapLocalVariables) { | ||||
| 	public static IMappingProvider create(MappingTree mappings, String from, String to, boolean remapLocalVariables) { | ||||
| 		return (acceptor) -> { | ||||
| 			for (ClassDef classDef : mappings.getClasses()) { | ||||
| 			for (MappingTree.ClassMapping classDef : mappings.getClasses()) { | ||||
| 				String className = classDef.getName(from); | ||||
| 				acceptor.acceptClass(className, classDef.getName(to)); | ||||
| 
 | ||||
| 				for (FieldDef field : classDef.getFields()) { | ||||
| 					acceptor.acceptField(memberOf(className, field.getName(from), field.getDescriptor(from)), field.getName(to)); | ||||
| 				for (MappingTree.FieldMapping field : classDef.getFields()) { | ||||
| 					acceptor.acceptField(memberOf(className, field.getName(from), field.getDesc(from)), field.getName(to)); | ||||
| 				} | ||||
| 
 | ||||
| 				for (MethodDef method : classDef.getMethods()) { | ||||
| 					IMappingProvider.Member methodIdentifier = memberOf(className, method.getName(from), method.getDescriptor(from)); | ||||
| 				for (MappingTree.MethodMapping method : classDef.getMethods()) { | ||||
| 					IMappingProvider.Member methodIdentifier = memberOf(className, method.getName(from), method.getDesc(from)); | ||||
| 					acceptor.acceptMethod(methodIdentifier, method.getName(to)); | ||||
| 
 | ||||
| 					if (remapLocalVariables) { | ||||
| 						for (ParameterDef parameter : method.getParameters()) { | ||||
| 							acceptor.acceptMethodArg(methodIdentifier, parameter.getLocalVariableIndex(), parameter.getName(to)); | ||||
| 						for (MappingTree.MethodArgMapping parameter : method.getArgs()) { | ||||
| 							String name = parameter.getName(to); | ||||
| 
 | ||||
| 							if (name == null) { | ||||
| 								continue; | ||||
| 							} | ||||
| 
 | ||||
| 							acceptor.acceptMethodArg(methodIdentifier, parameter.getLvIndex(), name); | ||||
| 						} | ||||
| 
 | ||||
| 						for (LocalVariableDef localVariable : method.getLocalVariables()) { | ||||
| 							acceptor.acceptMethodVar(methodIdentifier, localVariable.getLocalVariableIndex(), | ||||
| 									localVariable.getLocalVariableStartOffset(), localVariable.getLocalVariableTableIndex(), | ||||
| 						for (MappingTree.MethodVarMapping localVariable : method.getVars()) { | ||||
| 							acceptor.acceptMethodVar(methodIdentifier, localVariable.getLvIndex(), | ||||
| 									localVariable.getStartOpIdx(), localVariable.getLvtRowIndex(), | ||||
| 									localVariable.getName(to)); | ||||
| 						} | ||||
| 					} | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue