Improve setup speed. (#208)
* Improve access widener remapper, now uses tiny remapper * First pass on using the new tiny remapper * Optimise source remapping
This commit is contained in:
		
							parent
							
								
									bf6fb4a95e
								
							
						
					
					
						commit
						3eff7d0fdb
					
				
					 13 changed files with 420 additions and 362 deletions
				
			
		|  | @ -47,7 +47,7 @@ dependencies { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// tinyfile management | 	// tinyfile management | ||||||
| 	implementation ('net.fabricmc:tiny-remapper:0.2.2.66') { | 	implementation ('net.fabricmc:tiny-remapper:0.3.0.70') { | ||||||
| 		transitive = false | 		transitive = false | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -57,7 +57,6 @@ public class LoomGradleExtension { | ||||||
| 	public String loaderLaunchMethod; | 	public String loaderLaunchMethod; | ||||||
| 	public boolean remapMod = true; | 	public boolean remapMod = true; | ||||||
| 	public boolean autoGenIDERuns = true; | 	public boolean autoGenIDERuns = true; | ||||||
| 	public boolean extractJars = false; |  | ||||||
| 	public String customManifest = null; | 	public String customManifest = null; | ||||||
| 	public File accessWidener = null; | 	public File accessWidener = null; | ||||||
| 	public Function<String, Object> intermediaryUrl = mcVer -> "https://maven.fabricmc.net/net/fabricmc/intermediary/" + mcVer + "/intermediary-" + mcVer + "-v2.jar"; | 	public Function<String, Object> intermediaryUrl = mcVer -> "https://maven.fabricmc.net/net/fabricmc/intermediary/" + mcVer + "/intermediary-" + mcVer + "-v2.jar"; | ||||||
|  |  | ||||||
|  | @ -0,0 +1,104 @@ | ||||||
|  | /* | ||||||
|  |  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||||
|  |  * | ||||||
|  |  * Copyright (c) 2016, 2017, 2018 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.processors.dependency; | ||||||
|  | 
 | ||||||
|  | import java.io.File; | ||||||
|  | import java.io.IOException; | ||||||
|  | import java.io.InputStream; | ||||||
|  | import java.io.InputStreamReader; | ||||||
|  | import java.util.jar.JarEntry; | ||||||
|  | import java.util.jar.JarFile; | ||||||
|  | 
 | ||||||
|  | import com.google.gson.JsonObject; | ||||||
|  | 
 | ||||||
|  | import net.fabricmc.loom.util.ModProcessor; | ||||||
|  | 
 | ||||||
|  | public class ModDependencyInfo { | ||||||
|  | 	public final String group; | ||||||
|  | 	public final String name; | ||||||
|  | 	public final String version; | ||||||
|  | 	public final String classifier; | ||||||
|  | 	public final File inputFile; | ||||||
|  | 
 | ||||||
|  | 	public final RemapData remapData; | ||||||
|  | 
 | ||||||
|  | 	public ModDependencyInfo(String group, String name, String version, String classifier, File inputFile, RemapData remapData) { | ||||||
|  | 		this.group = group; | ||||||
|  | 		this.name = name; | ||||||
|  | 		this.version = version; | ||||||
|  | 		this.classifier = classifier; | ||||||
|  | 		this.inputFile = inputFile; | ||||||
|  | 		this.remapData = remapData; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public String getRemappedNotation() { | ||||||
|  | 		return String.format("%s:%s:%s@%s%s", group, name, version, remapData.mappingsSuffix, classifier); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public String getRemappedFilename() { | ||||||
|  | 		return String.format("%s-%s@%s", name, version, remapData.mappingsSuffix + classifier.replace(':', '-')); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public File getRemappedOutput() { | ||||||
|  | 		return new File(remapData.modStore, getRemappedFilename() + ".jar"); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public File getInputFile() { | ||||||
|  | 		return inputFile; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public boolean requiresRemapping() { | ||||||
|  | 		return !getRemappedOutput().exists() || inputFile.lastModified() <= 0 || inputFile.lastModified() > getRemappedOutput().lastModified(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public void finaliseRemapping() { | ||||||
|  | 		getRemappedOutput().setLastModified(inputFile.lastModified()); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Override | ||||||
|  | 	public String toString() { | ||||||
|  | 		return String.format("%s:%s:%s:%s", group, name, version, classifier); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public String getAccessWidener() throws IOException { | ||||||
|  | 		try (JarFile jarFile = new JarFile(getInputFile())) { | ||||||
|  | 			JarEntry modJsonEntry = jarFile.getJarEntry("fabric.mod.json"); | ||||||
|  | 
 | ||||||
|  | 			if (modJsonEntry == null) { | ||||||
|  | 				return null; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			try (InputStream inputStream = jarFile.getInputStream(modJsonEntry)) { | ||||||
|  | 				JsonObject json = ModProcessor.GSON.fromJson(new InputStreamReader(inputStream), JsonObject.class); | ||||||
|  | 
 | ||||||
|  | 				if (!json.has("accessWidener")) { | ||||||
|  | 					return null; | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				return json.get("accessWidener").getAsString(); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -0,0 +1,37 @@ | ||||||
|  | /* | ||||||
|  |  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||||
|  |  * | ||||||
|  |  * Copyright (c) 2016, 2017, 2018 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.processors.dependency; | ||||||
|  | 
 | ||||||
|  | import java.io.File; | ||||||
|  | 
 | ||||||
|  | public class RemapData { | ||||||
|  | 	public final String mappingsSuffix; | ||||||
|  | 	public final File modStore; | ||||||
|  | 
 | ||||||
|  | 	public RemapData(String mappingsSuffix, File modStore) { | ||||||
|  | 		this.mappingsSuffix = mappingsSuffix; | ||||||
|  | 		this.modStore = modStore; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -25,14 +25,19 @@ | ||||||
| package net.fabricmc.loom.providers; | package net.fabricmc.loom.providers; | ||||||
| 
 | 
 | ||||||
| import java.io.File; | import java.io.File; | ||||||
|  | import java.io.IOException; | ||||||
|  | import java.nio.file.Path; | ||||||
|  | import java.util.Arrays; | ||||||
| import java.util.Collection; | import java.util.Collection; | ||||||
| import java.util.function.Consumer; | import java.util.function.Consumer; | ||||||
| 
 | 
 | ||||||
| import org.gradle.api.Project; | import org.gradle.api.Project; | ||||||
| 
 | 
 | ||||||
|  | import net.fabricmc.loom.util.TinyRemapperMappingsHelper; | ||||||
|  | import net.fabricmc.tinyremapper.OutputConsumerPath; | ||||||
|  | import net.fabricmc.tinyremapper.TinyRemapper; | ||||||
| import net.fabricmc.loom.util.Constants; | import net.fabricmc.loom.util.Constants; | ||||||
| import net.fabricmc.loom.util.DependencyProvider; | import net.fabricmc.loom.util.DependencyProvider; | ||||||
| import net.fabricmc.loom.util.MapJarsTiny; |  | ||||||
| 
 | 
 | ||||||
| public class MinecraftMappedProvider extends DependencyProvider { | public class MinecraftMappedProvider extends DependencyProvider { | ||||||
| 	private File minecraftMappedJar; | 	private File minecraftMappedJar; | ||||||
|  | @ -66,7 +71,7 @@ public class MinecraftMappedProvider extends DependencyProvider { | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			try { | 			try { | ||||||
| 				new MapJarsTiny().mapJars(minecraftProvider, this, this.minecraftMappedJar, this.minecraftIntermediaryJar, getProject()); | 				mapMinecraftJar(); | ||||||
| 			} catch (Throwable t) { | 			} catch (Throwable t) { | ||||||
| 				//Cleanup some some things that may be in a bad state now | 				//Cleanup some some things that may be in a bad state now | ||||||
| 				minecraftMappedJar.delete(); | 				minecraftMappedJar.delete(); | ||||||
|  | @ -83,6 +88,47 @@ public class MinecraftMappedProvider extends DependencyProvider { | ||||||
| 		addDependencies(dependency, postPopulationScheduler); | 		addDependencies(dependency, postPopulationScheduler); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	private void mapMinecraftJar() throws IOException { | ||||||
|  | 		String fromM = "official"; | ||||||
|  | 
 | ||||||
|  | 		MappingsProvider mappingsProvider = getExtension().getMappingsProvider(); | ||||||
|  | 
 | ||||||
|  | 		Path input = minecraftProvider.getMergedJar().toPath(); | ||||||
|  | 		Path outputMapped = minecraftMappedJar.toPath(); | ||||||
|  | 		Path outputIntermediary = minecraftIntermediaryJar.toPath(); | ||||||
|  | 
 | ||||||
|  | 		for (String toM : Arrays.asList("named", "intermediary")) { | ||||||
|  | 			Path output = "named".equals(toM) ? outputMapped : outputIntermediary; | ||||||
|  | 
 | ||||||
|  | 			getProject().getLogger().lifecycle(":remapping minecraft (TinyRemapper, " + fromM + " -> " + toM + ")"); | ||||||
|  | 
 | ||||||
|  | 			TinyRemapper remapper = getTinyRemapper(fromM, toM); | ||||||
|  | 
 | ||||||
|  | 			try (OutputConsumerPath outputConsumer = new OutputConsumerPath.Builder(output).build()) { | ||||||
|  | 				outputConsumer.addNonClassFiles(input); | ||||||
|  | 				remapper.readClassPath(getRemapClasspath()); | ||||||
|  | 				remapper.readInputs(input); | ||||||
|  | 				remapper.apply(outputConsumer); | ||||||
|  | 			} catch (Exception e) { | ||||||
|  | 				throw new RuntimeException("Failed to remap JAR " + input + " with mappings from " + mappingsProvider.tinyMappings, e); | ||||||
|  | 			} finally { | ||||||
|  | 				remapper.finish(); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public TinyRemapper getTinyRemapper(String fromM, String toM) throws IOException { | ||||||
|  | 		return TinyRemapper.newRemapper() | ||||||
|  | 				.withMappings(TinyRemapperMappingsHelper.create(getExtension().getMappingsProvider().getMappings(), fromM, toM, true)) | ||||||
|  | 				.renameInvalidLocals(true) | ||||||
|  | 				.rebuildSourceFilenames(true) | ||||||
|  | 				.build(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public Path[] getRemapClasspath() { | ||||||
|  | 		return getMapperPaths().stream().map(File::toPath).toArray(Path[]::new); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	protected void addDependencies(DependencyInfo dependency, Consumer<Runnable> postPopulationScheduler) { | 	protected void addDependencies(DependencyInfo dependency, Consumer<Runnable> postPopulationScheduler) { | ||||||
| 		getProject().getRepositories().flatDir(repository -> repository.dir(getJarDirectory(getExtension().getUserCache(), "mapped"))); | 		getProject().getRepositories().flatDir(repository -> repository.dir(getJarDirectory(getExtension().getUserCache(), "mapped"))); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -110,11 +110,16 @@ public class RemapJarTask extends Jar { | ||||||
| 			remapper.readInputs(input); | 			remapper.readInputs(input); | ||||||
| 			remapper.apply(outputConsumer); | 			remapper.apply(outputConsumer); | ||||||
| 		} catch (Exception e) { | 		} catch (Exception e) { | ||||||
| 			throw new RuntimeException("Failed to remap " + input + " to " + output, e); |  | ||||||
| 		} finally { |  | ||||||
| 			remapper.finish(); | 			remapper.finish(); | ||||||
|  | 			throw new RuntimeException("Failed to remap " + input + " to " + output, e); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		if (extension.accessWidener != null) { | ||||||
|  | 			extension.getJarProcessorManager().getByType(AccessWidenerJarProcessor.class).remapAccessWidener(output, remapper.getRemapper()); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		remapper.finish(); | ||||||
|  | 
 | ||||||
| 		if (!Files.exists(output)) { | 		if (!Files.exists(output)) { | ||||||
| 			throw new RuntimeException("Failed to remap " + input + " to " + output + " - file missing!"); | 			throw new RuntimeException("Failed to remap " + input + " to " + output + " - file missing!"); | ||||||
| 		} | 		} | ||||||
|  | @ -129,10 +134,6 @@ public class RemapJarTask extends Jar { | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (extension.accessWidener != null) { |  | ||||||
| 			extension.getJarProcessorManager().getByType(AccessWidenerJarProcessor.class).remapAccessWidener(output); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		/*try { | 		/*try { | ||||||
| 			if (modJar.exists()) { | 			if (modJar.exists()) { | ||||||
| 				Files.move(modJar, modJarUnmappedCopy); | 				Files.move(modJar, modJarUnmappedCopy); | ||||||
|  |  | ||||||
|  | @ -116,11 +116,13 @@ public class LoomDependencyManager { | ||||||
| 			}); | 			}); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		SourceRemapper sourceRemapper = new SourceRemapper(project, true); | ||||||
|  | 
 | ||||||
| 		{ | 		{ | ||||||
| 			String mappingsKey = mappingsProvider.mappingsName + "." + mappingsProvider.minecraftVersion.replace(' ', '_').replace('.', '_').replace('-', '_') + "." + mappingsProvider.mappingsVersion; | 			String mappingsKey = mappingsProvider.mappingsName + "." + mappingsProvider.minecraftVersion.replace(' ', '_').replace('.', '_').replace('-', '_') + "." + mappingsProvider.mappingsVersion; | ||||||
| 
 | 
 | ||||||
| 			for (RemappedConfigurationEntry entry : Constants.MOD_COMPILE_ENTRIES) { | 			for (RemappedConfigurationEntry entry : Constants.MOD_COMPILE_ENTRIES) { | ||||||
| 				ModCompileRemapper.remapDependencies(project, mappingsKey, extension, project.getConfigurations().getByName(entry.getSourceConfiguration()), project.getConfigurations().getByName(entry.getRemappedConfiguration()), project.getConfigurations().getByName(entry.getTargetConfiguration(project.getConfigurations())), afterTasks::add); | 				ModCompileRemapper.remapDependencies(project, mappingsKey, extension, project.getConfigurations().getByName(entry.getSourceConfiguration()), project.getConfigurations().getByName(entry.getRemappedConfiguration()), project.getConfigurations().getByName(entry.getTargetConfiguration(project.getConfigurations())), sourceRemapper); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -150,6 +152,8 @@ public class LoomDependencyManager { | ||||||
| 			project.getLogger().warn("fabric-installer.json not found in classpath!"); | 			project.getLogger().warn("fabric-installer.json not found in classpath!"); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		sourceRemapper.remapAll(); | ||||||
|  | 
 | ||||||
| 		for (Runnable runnable : afterTasks) { | 		for (Runnable runnable : afterTasks) { | ||||||
| 			runnable.run(); | 			runnable.run(); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -1,77 +0,0 @@ | ||||||
| /* |  | ||||||
|  * This file is part of fabric-loom, licensed under the MIT License (MIT). |  | ||||||
|  * |  | ||||||
|  * Copyright (c) 2016, 2017, 2018 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.util; |  | ||||||
| 
 |  | ||||||
| import java.io.File; |  | ||||||
| import java.io.IOException; |  | ||||||
| import java.nio.file.Path; |  | ||||||
| import java.util.Arrays; |  | ||||||
| 
 |  | ||||||
| import org.gradle.api.Project; |  | ||||||
| 
 |  | ||||||
| import net.fabricmc.loom.LoomGradleExtension; |  | ||||||
| import net.fabricmc.loom.providers.MappingsProvider; |  | ||||||
| import net.fabricmc.loom.providers.MinecraftMappedProvider; |  | ||||||
| import net.fabricmc.loom.providers.MinecraftProvider; |  | ||||||
| import net.fabricmc.tinyremapper.OutputConsumerPath; |  | ||||||
| import net.fabricmc.tinyremapper.TinyRemapper; |  | ||||||
| 
 |  | ||||||
| public class MapJarsTiny { |  | ||||||
| 	public void mapJars(MinecraftProvider jarProvider, MinecraftMappedProvider mapProvider, File mappedJar, File intermediaryJar, Project project) throws IOException { |  | ||||||
| 		String fromM = "official"; |  | ||||||
| 
 |  | ||||||
| 		LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); |  | ||||||
| 		MappingsProvider mappingsProvider = extension.getMappingsProvider(); |  | ||||||
| 
 |  | ||||||
| 		Path[] classpath = mapProvider.getMapperPaths().stream().map(File::toPath).toArray(Path[]::new); |  | ||||||
| 
 |  | ||||||
| 		Path input = jarProvider.getMergedJar().toPath(); |  | ||||||
| 		Path outputMapped = mappedJar.toPath(); |  | ||||||
| 		Path outputIntermediary = intermediaryJar.toPath(); |  | ||||||
| 
 |  | ||||||
| 		for (String toM : Arrays.asList("named", "intermediary")) { |  | ||||||
| 			Path output = "named".equals(toM) ? outputMapped : outputIntermediary; |  | ||||||
| 
 |  | ||||||
| 			project.getLogger().lifecycle(":remapping minecraft (TinyRemapper, " + fromM + " -> " + toM + ")"); |  | ||||||
| 
 |  | ||||||
| 			TinyRemapper remapper = TinyRemapper.newRemapper() |  | ||||||
| 							.withMappings(TinyRemapperMappingsHelper.create(mappingsProvider.getMappings(), fromM, toM, true)) |  | ||||||
| 							.renameInvalidLocals(true) |  | ||||||
| 							.rebuildSourceFilenames(true) |  | ||||||
| 							.build(); |  | ||||||
| 
 |  | ||||||
| 			try (OutputConsumerPath outputConsumer = new OutputConsumerPath.Builder(output).build()) { |  | ||||||
| 				outputConsumer.addNonClassFiles(input); |  | ||||||
| 				remapper.readClassPath(classpath); |  | ||||||
| 				remapper.readInputs(input); |  | ||||||
| 				remapper.apply(outputConsumer); |  | ||||||
| 			} catch (Exception e) { |  | ||||||
| 				throw new RuntimeException("Failed to remap JAR " + input + " with mappings from " + mappingsProvider.tinyMappings, e); |  | ||||||
| 			} finally { |  | ||||||
| 				remapper.finish(); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  | @ -26,7 +26,9 @@ package net.fabricmc.loom.util; | ||||||
| 
 | 
 | ||||||
| import java.io.File; | import java.io.File; | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
| import java.util.function.Consumer; | import java.util.ArrayList; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.stream.Collectors; | ||||||
| import java.util.zip.ZipFile; | import java.util.zip.ZipFile; | ||||||
| 
 | 
 | ||||||
| import org.gradle.api.Project; | import org.gradle.api.Project; | ||||||
|  | @ -45,12 +47,19 @@ import org.gradle.jvm.JvmLibrary; | ||||||
| import org.gradle.language.base.artifact.SourcesArtifact; | import org.gradle.language.base.artifact.SourcesArtifact; | ||||||
| 
 | 
 | ||||||
| import net.fabricmc.loom.LoomGradleExtension; | import net.fabricmc.loom.LoomGradleExtension; | ||||||
|  | import net.fabricmc.loom.processors.dependency.ModDependencyInfo; | ||||||
|  | import net.fabricmc.loom.processors.dependency.RemapData; | ||||||
| 
 | 
 | ||||||
| public class ModCompileRemapper { | public class ModCompileRemapper { | ||||||
| 	public static void remapDependencies(Project project, String mappingsSuffix, LoomGradleExtension extension, Configuration modCompile, Configuration modCompileRemapped, Configuration regularCompile, Consumer<Runnable> postPopulationScheduler) { | 	public static void remapDependencies(Project project, String mappingsSuffix, LoomGradleExtension extension, Configuration modCompile, Configuration modCompileRemapped, Configuration regularCompile, SourceRemapper sourceRemapper) { | ||||||
| 		Logger logger = project.getLogger(); | 		Logger logger = project.getLogger(); | ||||||
| 		DependencyHandler dependencies = project.getDependencies(); | 		DependencyHandler dependencies = project.getDependencies(); | ||||||
| 
 | 
 | ||||||
|  | 		final File modStore = extension.getRemappedModCache(); | ||||||
|  | 		final RemapData remapData = new RemapData(mappingsSuffix, modStore); | ||||||
|  | 
 | ||||||
|  | 		final List<ModDependencyInfo> modDependencies = new ArrayList<>(); | ||||||
|  | 
 | ||||||
| 		for (ResolvedArtifact artifact : modCompile.getResolvedConfiguration().getResolvedArtifacts()) { | 		for (ResolvedArtifact artifact : modCompile.getResolvedConfiguration().getResolvedArtifacts()) { | ||||||
| 			String group; | 			String group; | ||||||
| 			String name; | 			String name; | ||||||
|  | @ -76,21 +85,32 @@ public class ModCompileRemapper { | ||||||
| 
 | 
 | ||||||
| 			File sources = findSources(dependencies, artifact); | 			File sources = findSources(dependencies, artifact); | ||||||
| 
 | 
 | ||||||
|  | 			ModDependencyInfo info = new ModDependencyInfo(group, name, version, classifierSuffix, artifact.getFile(), remapData); | ||||||
|  | 			modDependencies.add(info); | ||||||
|  | 
 | ||||||
| 			String remappedLog = group + ":" + name + ":" + version + classifierSuffix + " (" + mappingsSuffix + ")"; | 			String remappedLog = group + ":" + name + ":" + version + classifierSuffix + " (" + mappingsSuffix + ")"; | ||||||
| 			String remappedNotation = String.format("%s:%s:%s@%s%s", group, name, version, mappingsSuffix, classifierSuffix); |  | ||||||
| 			String remappedFilename = String.format("%s-%s@%s", name, version, mappingsSuffix + classifierSuffix.replace(':', '-')); | 			String remappedFilename = String.format("%s-%s@%s", name, version, mappingsSuffix + classifierSuffix.replace(':', '-')); | ||||||
| 			project.getLogger().info(":providing " + remappedLog); | 			project.getLogger().info(":providing " + remappedLog); | ||||||
| 
 | 
 | ||||||
| 			File modStore = extension.getRemappedModCache(); |  | ||||||
| 
 |  | ||||||
| 			remapArtifact(project, modCompileRemapped, artifact, remappedFilename, modStore); |  | ||||||
| 
 |  | ||||||
| 			project.getDependencies().add(modCompileRemapped.getName(), project.getDependencies().module(remappedNotation)); |  | ||||||
| 
 |  | ||||||
| 			if (sources != null) { | 			if (sources != null) { | ||||||
| 				scheduleSourcesRemapping(project, postPopulationScheduler, sources, remappedLog, remappedFilename, modStore); | 				scheduleSourcesRemapping(project, sourceRemapper, sources, remappedLog, remappedFilename, modStore); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | 
 | ||||||
|  | 		List<ModDependencyInfo> processList = modDependencies.stream() | ||||||
|  | 				.filter(ModDependencyInfo::requiresRemapping) | ||||||
|  | 				.collect(Collectors.toList()); | ||||||
|  | 
 | ||||||
|  | 		try { | ||||||
|  | 			ModProcessor.processMods(project, processList); | ||||||
|  | 		} catch (IOException e) { | ||||||
|  | 			throw new RuntimeException("Failed to remap mods", e); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// Add all of the remapped mods onto the config | ||||||
|  | 		for (ModDependencyInfo modDependency : modDependencies) { | ||||||
|  | 			project.getDependencies().add(modCompileRemapped.getName(), project.getDependencies().module(modDependency.getRemappedNotation())); | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/** | 	/** | ||||||
|  | @ -123,28 +143,6 @@ public class ModCompileRemapper { | ||||||
| 		dependencies.add(regularCompile.getName(), dep); | 		dependencies.add(regularCompile.getName(), dep); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private static void remapArtifact(Project project, Configuration config, ResolvedArtifact artifact, String remappedFilename, File modStore) { |  | ||||||
| 		File input = artifact.getFile(); |  | ||||||
| 		File output = new File(modStore, remappedFilename + ".jar"); |  | ||||||
| 
 |  | ||||||
| 		if (!output.exists() || input.lastModified() <= 0 || input.lastModified() > output.lastModified()) { |  | ||||||
| 			//If the output doesn't exist, or appears to be outdated compared to the input we'll remap it |  | ||||||
| 			try { |  | ||||||
| 				ModProcessor.processMod(input, output, project, config, artifact); |  | ||||||
| 			} catch (IOException e) { |  | ||||||
| 				throw new RuntimeException("Failed to remap mod", e); |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			if (!output.exists()) { |  | ||||||
| 				throw new RuntimeException("Failed to remap mod"); |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			output.setLastModified(input.lastModified()); |  | ||||||
| 		} else { |  | ||||||
| 			project.getLogger().info(output.getName() + " is up to date with " + input.getName()); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public static File findSources(DependencyHandler dependencies, ResolvedArtifact artifact) { | 	public static File findSources(DependencyHandler dependencies, ResolvedArtifact artifact) { | ||||||
| 		@SuppressWarnings("unchecked") ArtifactResolutionQuery query = dependencies.createArtifactResolutionQuery()// | 		@SuppressWarnings("unchecked") ArtifactResolutionQuery query = dependencies.createArtifactResolutionQuery()// | ||||||
| 				.forComponents(artifact.getId().getComponentIdentifier())// | 				.forComponents(artifact.getId().getComponentIdentifier())// | ||||||
|  | @ -161,23 +159,21 @@ public class ModCompileRemapper { | ||||||
| 		return null; | 		return null; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private static void scheduleSourcesRemapping(Project project, Consumer<Runnable> postPopulationScheduler, File sources, String remappedLog, String remappedFilename, File modStore) { | 	private static void scheduleSourcesRemapping(Project project, SourceRemapper sourceRemapper, File sources, String remappedLog, String remappedFilename, File modStore) { | ||||||
| 		postPopulationScheduler.accept(() -> { | 		project.getLogger().info(":providing " + remappedLog + " sources"); | ||||||
| 			project.getLogger().info(":providing " + remappedLog + " sources"); | 		File remappedSources = new File(modStore, remappedFilename + "-sources.jar"); | ||||||
| 			File remappedSources = new File(modStore, remappedFilename + "-sources.jar"); |  | ||||||
| 
 | 
 | ||||||
| 			if (!remappedSources.exists() || sources.lastModified() <= 0 || sources.lastModified() > remappedSources.lastModified()) { | 		if (!remappedSources.exists() || sources.lastModified() <= 0 || sources.lastModified() > remappedSources.lastModified()) { | ||||||
| 				try { | 			try { | ||||||
| 					SourceRemapper.remapSources(project, sources, remappedSources, true); | 				sourceRemapper.scheduleRemapSources(sources, remappedSources); | ||||||
| 
 | 
 | ||||||
| 					//Set the remapped sources creation date to match the sources if we're likely succeeded in making it | 				//Set the remapped sources creation date to match the sources if we're likely succeeded in making it | ||||||
| 					remappedSources.setLastModified(sources.lastModified()); | 				remappedSources.setLastModified(sources.lastModified()); | ||||||
| 				} catch (Exception e) { | 			} catch (Exception e) { | ||||||
| 					e.printStackTrace(); | 				e.printStackTrace(); | ||||||
| 				} |  | ||||||
| 			} else { |  | ||||||
| 				project.getLogger().info(remappedSources.getName() + " is up to date with " + sources.getName()); |  | ||||||
| 			} | 			} | ||||||
| 		}); | 		} else { | ||||||
|  | 			project.getLogger().info(remappedSources.getName() + " is up to date with " + sources.getName()); | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -25,31 +25,28 @@ | ||||||
| package net.fabricmc.loom.util; | package net.fabricmc.loom.util; | ||||||
| 
 | 
 | ||||||
| import java.io.BufferedReader; | import java.io.BufferedReader; | ||||||
|  | import java.io.ByteArrayInputStream; | ||||||
| import java.io.File; | import java.io.File; | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
| import java.io.InputStream; | import java.io.InputStream; | ||||||
| import java.io.InputStreamReader; | import java.io.InputStreamReader; | ||||||
| import java.io.StringReader; |  | ||||||
| import java.io.StringWriter; | import java.io.StringWriter; | ||||||
| import java.nio.charset.StandardCharsets; | import java.nio.charset.StandardCharsets; | ||||||
| import java.nio.file.Path; | import java.nio.file.Path; | ||||||
| import java.nio.file.Paths; | import java.util.HashMap; | ||||||
| import java.util.HashSet; | import java.util.List; | ||||||
| import java.util.Set; | import java.util.Map; | ||||||
| import java.util.jar.JarEntry; | import java.util.function.BiConsumer; | ||||||
| import java.util.jar.JarFile; | import java.util.jar.JarFile; | ||||||
| import java.util.zip.ZipEntry; | import java.util.zip.ZipEntry; | ||||||
| 
 | 
 | ||||||
| import com.google.gson.Gson; | import com.google.gson.Gson; | ||||||
| import com.google.gson.GsonBuilder; | import com.google.gson.GsonBuilder; | ||||||
| import com.google.gson.JsonArray; |  | ||||||
| import com.google.gson.JsonObject; | import com.google.gson.JsonObject; | ||||||
| import org.apache.commons.io.IOUtils; | import org.apache.commons.io.IOUtils; | ||||||
| import org.gradle.api.Project; | import org.gradle.api.Project; | ||||||
| import org.gradle.api.artifacts.Configuration; | import org.objectweb.asm.commons.Remapper; | ||||||
| import org.gradle.api.artifacts.ResolvedArtifact; |  | ||||||
| import org.zeroturnaround.zip.ZipUtil; | import org.zeroturnaround.zip.ZipUtil; | ||||||
| import org.zeroturnaround.zip.commons.FileUtils; |  | ||||||
| import org.zeroturnaround.zip.transform.StringZipEntryTransformer; | import org.zeroturnaround.zip.transform.StringZipEntryTransformer; | ||||||
| import org.zeroturnaround.zip.transform.ZipEntryTransformerEntry; | import org.zeroturnaround.zip.transform.ZipEntryTransformerEntry; | ||||||
| 
 | 
 | ||||||
|  | @ -58,82 +55,34 @@ import net.fabricmc.loom.providers.MappingsProvider; | ||||||
| import net.fabricmc.loom.providers.MinecraftMappedProvider; | import net.fabricmc.loom.providers.MinecraftMappedProvider; | ||||||
| import net.fabricmc.loom.util.accesswidener.AccessWidener; | import net.fabricmc.loom.util.accesswidener.AccessWidener; | ||||||
| import net.fabricmc.loom.util.accesswidener.AccessWidenerRemapper; | import net.fabricmc.loom.util.accesswidener.AccessWidenerRemapper; | ||||||
| import net.fabricmc.tinyremapper.OutputConsumerPath; | import net.fabricmc.loom.processors.dependency.ModDependencyInfo; | ||||||
| import net.fabricmc.tinyremapper.TinyRemapper; | import net.fabricmc.tinyremapper.TinyRemapper; | ||||||
|  | import net.fabricmc.tinyremapper.InputTag; | ||||||
|  | import net.fabricmc.tinyremapper.OutputConsumerPath; | ||||||
| 
 | 
 | ||||||
| public class ModProcessor { | public class ModProcessor { | ||||||
| 	private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); | 	public static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); | ||||||
| 
 | 
 | ||||||
| 	public static void processMod(File input, File output, Project project, Configuration config, ResolvedArtifact artifact) throws IOException { | 	public static void processMods(Project project, List<ModDependencyInfo> processList) throws IOException { | ||||||
| 		if (output.exists()) { | 		if (processList.isEmpty()) { | ||||||
| 			output.delete(); | 			return; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		remapJar(input, output, project, artifact); | 		for (ModDependencyInfo info : processList) { | ||||||
| 
 | 			if (info.getRemappedOutput().exists()) { | ||||||
| 		//Enable this if you want your nested jars to be extracted, this will extract **all** jars | 				info.getRemappedOutput().delete(); | ||||||
| 		if (project.getExtensions().getByType(LoomGradleExtension.class).extractJars) { |  | ||||||
| 			handleNestedJars(input, project, config, artifact); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		remapaccessWidener(output, project); |  | ||||||
| 
 |  | ||||||
| 		//Always strip the nested jars |  | ||||||
| 		stripNestedJars(output); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	private static void handleNestedJars(File input, Project project, Configuration config, ResolvedArtifact artifact) throws IOException { |  | ||||||
| 		try (JarFile jarFile = new JarFile(input)) { |  | ||||||
| 			JarEntry modJsonEntry = jarFile.getJarEntry("fabric.mod.json"); |  | ||||||
| 
 |  | ||||||
| 			if (modJsonEntry == null) { |  | ||||||
| 				return; |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			try (InputStream inputStream = jarFile.getInputStream(modJsonEntry)) { |  | ||||||
| 				JsonObject json = GSON.fromJson(new InputStreamReader(inputStream), JsonObject.class); |  | ||||||
| 
 |  | ||||||
| 				if (json == null || !json.has("jars")) { |  | ||||||
| 					return; |  | ||||||
| 				} |  | ||||||
| 
 |  | ||||||
| 				JsonArray jsonArray = json.getAsJsonArray("jars"); |  | ||||||
| 
 |  | ||||||
| 				for (int i = 0; i < jsonArray.size(); i++) { |  | ||||||
| 					JsonObject jsonObject = jsonArray.get(i).getAsJsonObject(); |  | ||||||
| 					String fileName = jsonObject.get("file").getAsString(); |  | ||||||
| 					project.getLogger().lifecycle(String.format("Found %s nested in %s", fileName, input.getName())); |  | ||||||
| 					processNestedJar(jarFile, fileName, project, config, artifact); |  | ||||||
| 				} |  | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	private static void processNestedJar(JarFile parentJar, String fileName, Project project, Configuration config, ResolvedArtifact artifact) throws IOException { | 		remapJars(project, processList); | ||||||
| 		LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); |  | ||||||
| 
 | 
 | ||||||
| 		JarEntry entry = parentJar.getJarEntry(fileName); | 		for (ModDependencyInfo info : processList) { | ||||||
|  | 			if (!info.getRemappedOutput().exists()) { | ||||||
|  | 				throw new RuntimeException("Failed to remap mod" + info); | ||||||
|  | 			} | ||||||
| 
 | 
 | ||||||
| 		if (entry == null) { | 			stripNestedJars(info.getRemappedOutput()); | ||||||
| 			throw new RuntimeException(String.format("%s was not found in %s", fileName, parentJar.getName())); |  | ||||||
| 		} | 		} | ||||||
| 
 |  | ||||||
| 		File nestedFile = new File(extension.getNestedModCache(), fileName.substring(fileName.lastIndexOf("/"))); |  | ||||||
| 
 |  | ||||||
| 		try (InputStream jarStream = parentJar.getInputStream(entry)) { |  | ||||||
| 			FileUtils.copy(jarStream, nestedFile); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		File remappedFile = new File(extension.getRemappedModCache(), fileName.substring(fileName.lastIndexOf("/"))); |  | ||||||
| 
 |  | ||||||
| 		processMod(nestedFile, remappedFile, project, config, artifact); |  | ||||||
| 
 |  | ||||||
| 		if (!remappedFile.exists()) { |  | ||||||
| 			throw new RuntimeException("Failed to find processed nested jar"); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		//Add the project right onto the remapped mods, hopefully this works |  | ||||||
| 		project.getDependencies().add(config.getName(), project.files(remappedFile)); |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private static void stripNestedJars(File file) { | 	private static void stripNestedJars(File file) { | ||||||
|  | @ -148,57 +97,24 @@ public class ModProcessor { | ||||||
| 		}))}); | 		}))}); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private static void remapaccessWidener(File input, Project project) throws IOException { | 	private static byte[] remapaccessWidener(byte[] input, Remapper remapper) { | ||||||
| 		String accessWidenerPath; | 		try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(input), StandardCharsets.UTF_8))) { | ||||||
| 
 |  | ||||||
| 		try (JarFile jarFile = new JarFile(input)) { |  | ||||||
| 			JarEntry modJsonEntry = jarFile.getJarEntry("fabric.mod.json"); |  | ||||||
| 
 |  | ||||||
| 			if (modJsonEntry == null) { |  | ||||||
| 				return; |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			try (InputStream inputStream = jarFile.getInputStream(modJsonEntry)) { |  | ||||||
| 				JsonObject json = GSON.fromJson(new InputStreamReader(inputStream), JsonObject.class); |  | ||||||
| 
 |  | ||||||
| 				if (!json.has("accessWidener")) { |  | ||||||
| 					return; |  | ||||||
| 				} |  | ||||||
| 
 |  | ||||||
| 				accessWidenerPath = json.get("accessWidener").getAsString(); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (accessWidenerPath == null) { |  | ||||||
| 			return; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		ZipUtil.transformEntry(input, accessWidenerPath, new StringZipEntryTransformer() { |  | ||||||
| 			@Override |  | ||||||
| 			protected String transform(ZipEntry zipEntry, String input) throws IOException { |  | ||||||
| 				return remapaccessWidener(input, project); |  | ||||||
| 			} |  | ||||||
| 		}); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	private static String remapaccessWidener(String input, Project project) { |  | ||||||
| 		try (BufferedReader bufferedReader = new BufferedReader(new StringReader(input))) { |  | ||||||
| 			AccessWidener accessWidener = new AccessWidener(); | 			AccessWidener accessWidener = new AccessWidener(); | ||||||
| 			accessWidener.read(bufferedReader); | 			accessWidener.read(bufferedReader); | ||||||
| 
 | 
 | ||||||
| 			AccessWidenerRemapper accessWidenerRemapper = new AccessWidenerRemapper(accessWidener, project.getExtensions().getByType(LoomGradleExtension.class).getMappingsProvider().getMappings(), "named"); | 			AccessWidenerRemapper accessWidenerRemapper = new AccessWidenerRemapper(accessWidener, remapper, "named"); | ||||||
| 			AccessWidener remapped = accessWidenerRemapper.remap(); | 			AccessWidener remapped = accessWidenerRemapper.remap(); | ||||||
| 
 | 
 | ||||||
| 			try (StringWriter writer = new StringWriter()) { | 			try (StringWriter writer = new StringWriter()) { | ||||||
| 				remapped.write(writer); | 				remapped.write(writer); | ||||||
| 				return writer.toString(); | 				return writer.toString().getBytes(StandardCharsets.UTF_8); | ||||||
| 			} | 			} | ||||||
| 		} catch (IOException e) { | 		} catch (IOException e) { | ||||||
| 			throw new RuntimeException(e); | 			throw new RuntimeException(e); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private static void remapJar(File input, File output, Project project, ResolvedArtifact artifact) throws IOException { | 	private static void remapJars(Project project, List<ModDependencyInfo> processList) throws IOException { | ||||||
| 		LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); | 		LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); | ||||||
| 		String fromM = "intermediary"; | 		String fromM = "intermediary"; | ||||||
| 		String toM = "named"; | 		String toM = "named"; | ||||||
|  | @ -206,47 +122,57 @@ public class ModProcessor { | ||||||
| 		MinecraftMappedProvider mappedProvider = extension.getMinecraftMappedProvider(); | 		MinecraftMappedProvider mappedProvider = extension.getMinecraftMappedProvider(); | ||||||
| 		MappingsProvider mappingsProvider = extension.getMappingsProvider(); | 		MappingsProvider mappingsProvider = extension.getMappingsProvider(); | ||||||
| 
 | 
 | ||||||
| 		Path inputPath = input.getAbsoluteFile().toPath(); |  | ||||||
| 		Path mc = mappedProvider.getIntermediaryJar().toPath(); | 		Path mc = mappedProvider.getIntermediaryJar().toPath(); | ||||||
| 		Path[] mcDeps = mappedProvider.getMapperPaths().stream().map(File::toPath).toArray(Path[]::new); | 		Path[] mcDeps = mappedProvider.getMapperPaths().stream().map(File::toPath).toArray(Path[]::new); | ||||||
| 		Set<Path> modCompiles = new HashSet<>(); |  | ||||||
| 
 | 
 | ||||||
| 		for (RemappedConfigurationEntry entry : Constants.MOD_COMPILE_ENTRIES) { | 		project.getLogger().lifecycle(":remapping " + processList.size() + " mods (TinyRemapper, " + fromM + " -> " + toM + ")"); | ||||||
| 			project.getConfigurations().getByName(entry.getSourceConfiguration()).getFiles().stream().filter((f) -> !f.equals(input)).map(p -> { |  | ||||||
| 				if (p.equals(input)) { |  | ||||||
| 					return inputPath; |  | ||||||
| 				} else { |  | ||||||
| 					return p.toPath(); |  | ||||||
| 				} |  | ||||||
| 			}).forEach(modCompiles::add); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		project.getLogger().lifecycle(":remapping " + input.getName() + " (TinyRemapper, " + fromM + " -> " + toM + ")"); |  | ||||||
| 
 |  | ||||||
| 		// If the sources don't exist, we want remapper to give nicer names to the missing variable names. |  | ||||||
| 		// However, if the sources do exist, if remapper gives names to the parameters that prevents IDEs (at least IDEA) |  | ||||||
| 		// from replacing the parameters with the actual names from the sources. |  | ||||||
| 		boolean sourcesExist = ModCompileRemapper.findSources(project.getDependencies(), artifact) != null; |  | ||||||
| 
 | 
 | ||||||
| 		TinyRemapper remapper = TinyRemapper.newRemapper() | 		TinyRemapper remapper = TinyRemapper.newRemapper() | ||||||
| 						.withMappings(TinyRemapperMappingsHelper.create(mappingsProvider.getMappings(), fromM, toM, false)) | 						.withMappings(TinyRemapperMappingsHelper.create(mappingsProvider.getMappings(), fromM, toM, false)) | ||||||
| 						.renameInvalidLocals(!sourcesExist) | 						.renameInvalidLocals(false) | ||||||
| 						.build(); | 						.build(); | ||||||
| 
 | 
 | ||||||
| 		try (OutputConsumerPath outputConsumer = new OutputConsumerPath.Builder(Paths.get(output.getAbsolutePath())).build()) { | 		remapper.readClassPathAsync(mc); | ||||||
| 			outputConsumer.addNonClassFiles(inputPath); | 		remapper.readClassPathAsync(mcDeps); | ||||||
| 			remapper.readClassPath(modCompiles.toArray(new Path[0])); | 
 | ||||||
| 			remapper.readClassPath(mc); | 		final Map<ModDependencyInfo, InputTag> tagMap = new HashMap<>(); | ||||||
| 			remapper.readClassPath(mcDeps); | 		final Map<ModDependencyInfo, OutputConsumerPath> outputConsumerMap = new HashMap<>(); | ||||||
| 			remapper.readInputs(inputPath); | 
 | ||||||
| 			remapper.apply(outputConsumer); | 		for (ModDependencyInfo info : processList) { | ||||||
| 		} finally { | 			InputTag tag = remapper.createInputTag(); | ||||||
| 			remapper.finish(); | 			remapper.readInputsAsync(tag, info.getInputFile().toPath()); | ||||||
|  | 			tagMap.put(info, tag); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (!output.exists()) { | 		// Apply this in a second loop as we need to ensure all the inputs are on the classpath before remapping. | ||||||
| 			throw new RuntimeException("Failed to remap JAR to " + toM + " file not found: " + output.getAbsolutePath()); | 		for (ModDependencyInfo info : processList) { | ||||||
|  | 			OutputConsumerPath outputConsumer = new OutputConsumerPath.Builder(info.getRemappedOutput().toPath()).build(); | ||||||
|  | 			outputConsumer.addNonClassFiles(info.getInputFile().toPath()); | ||||||
|  | 			outputConsumerMap.put(info, outputConsumer); | ||||||
|  | 			String accessWidener = info.getAccessWidener(); | ||||||
|  | 
 | ||||||
|  | 			if (accessWidener == null) { | ||||||
|  | 				remapper.apply(outputConsumer, tagMap.get(info)); | ||||||
|  | 			} else { | ||||||
|  | 				remapper.apply(remapAccessWidener(remapper.getRemapper(), accessWidener, outputConsumer), tagMap.get(info)); | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
|  | 
 | ||||||
|  | 		remapper.finish(); | ||||||
|  | 
 | ||||||
|  | 		for (ModDependencyInfo info : processList) { | ||||||
|  | 			outputConsumerMap.get(info).close(); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	static BiConsumer<String, byte[]> remapAccessWidener(Remapper remapper, String accessWidener, BiConsumer<String, byte[]> output) { | ||||||
|  | 		return (s, bytes) -> { | ||||||
|  | 			if (s.equals(accessWidener)) { | ||||||
|  | 				output.accept(s, remapaccessWidener(bytes, remapper)); | ||||||
|  | 			} else { | ||||||
|  | 				output.accept(s, bytes); | ||||||
|  | 			} | ||||||
|  | 		}; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	static JsonObject readInstallerJson(File file, Project project) { | 	static JsonObject readInstallerJson(File file, Project project) { | ||||||
|  |  | ||||||
|  | @ -28,6 +28,8 @@ import java.io.File; | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
| import java.nio.file.Files; | import java.nio.file.Files; | ||||||
| import java.nio.file.Path; | import java.nio.file.Path; | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.List; | ||||||
| 
 | 
 | ||||||
| import org.cadixdev.lorenz.MappingSet; | import org.cadixdev.lorenz.MappingSet; | ||||||
| import org.cadixdev.lorenz.io.MappingsReader; | import org.cadixdev.lorenz.io.MappingsReader; | ||||||
|  | @ -46,44 +48,46 @@ import net.fabricmc.mapping.tree.TinyTree; | ||||||
| import net.fabricmc.stitch.util.StitchUtil; | import net.fabricmc.stitch.util.StitchUtil; | ||||||
| 
 | 
 | ||||||
| public class SourceRemapper { | public class SourceRemapper { | ||||||
| 	public static void remapSources(Project project, File source, File destination, boolean toNamed) throws Exception { | 	private final Project project; | ||||||
| 		remapSourcesInner(project, source, destination, toNamed); | 	private final boolean toNamed; | ||||||
|  | 	private final List<Runnable> remapTasks = new ArrayList<>(); | ||||||
|  | 
 | ||||||
|  | 	private Mercury mercury; | ||||||
|  | 
 | ||||||
|  | 	public SourceRemapper(Project project, boolean toNamed) { | ||||||
|  | 		this.project = project; | ||||||
|  | 		this.toNamed = toNamed; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public static void remapSources(Project project, File input, File output, boolean named) throws Exception { | ||||||
|  | 		SourceRemapper sourceRemapper = new SourceRemapper(project, named); | ||||||
|  | 		sourceRemapper.scheduleRemapSources(input, output); | ||||||
|  | 		sourceRemapper.remapAll(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public void scheduleRemapSources(File source, File destination) throws Exception { | ||||||
|  | 		remapTasks.add(() -> { | ||||||
|  | 			try { | ||||||
|  | 				remapSourcesInner(source, destination); | ||||||
|  | 			} catch (Exception e) { | ||||||
|  | 				throw new RuntimeException("Failed to remap sources for " + source, e); | ||||||
|  | 			} | ||||||
|  | 		}); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public void remapAll() { | ||||||
|  | 		if (!remapTasks.isEmpty()) { | ||||||
|  | 			project.getLogger().lifecycle(":remapping sources"); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		remapTasks.forEach(Runnable::run); | ||||||
| 		// TODO: FIXME - WORKAROUND https://github.com/FabricMC/fabric-loom/issues/45 | 		// TODO: FIXME - WORKAROUND https://github.com/FabricMC/fabric-loom/issues/45 | ||||||
| 		System.gc(); | 		System.gc(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private static void remapSourcesInner(Project project, File source, File destination, boolean toNamed) throws Exception { | 	private void remapSourcesInner(File source, File destination) throws Exception { | ||||||
| 		LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); |  | ||||||
| 		MappingsProvider mappingsProvider = extension.getMappingsProvider(); |  | ||||||
| 
 |  | ||||||
| 		MappingSet mappings = extension.getOrCreateSrcMappingCache(toNamed ? 1 : 0, () -> { |  | ||||||
| 			try { |  | ||||||
| 				TinyTree m = mappingsProvider.getMappings(); |  | ||||||
| 				project.getLogger().lifecycle(":loading " + (toNamed ? "intermediary -> named" : "named -> intermediary") + " source mappings"); |  | ||||||
| 				return new TinyReader(m, toNamed ? "intermediary" : "named", toNamed ? "named" : "intermediary").read(); |  | ||||||
| 			} catch (Exception e) { |  | ||||||
| 				throw new RuntimeException(e); |  | ||||||
| 			} |  | ||||||
| 		}); |  | ||||||
| 
 |  | ||||||
| 		project.getLogger().info(":remapping source jar"); | 		project.getLogger().info(":remapping source jar"); | ||||||
| 
 | 		Mercury mercury = getMercuryInstance(); | ||||||
| 		Mercury mercury = extension.getOrCreateSrcMercuryCache(toNamed ? 1 : 0, () -> { |  | ||||||
| 			Mercury m = createMercuryWithClassPath(project, toNamed); |  | ||||||
| 
 |  | ||||||
| 			for (Path file : extension.getUnmappedMods()) { |  | ||||||
| 				if (Files.isRegularFile(file)) { |  | ||||||
| 					m.getClassPath().add(file); |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			m.getClassPath().add(extension.getMinecraftMappedProvider().getMappedJar().toPath()); |  | ||||||
| 			m.getClassPath().add(extension.getMinecraftMappedProvider().getIntermediaryJar().toPath()); |  | ||||||
| 
 |  | ||||||
| 			m.getProcessors().add(MercuryRemapper.create(mappings)); |  | ||||||
| 
 |  | ||||||
| 			return m; |  | ||||||
| 		}); |  | ||||||
| 
 | 
 | ||||||
| 		if (source.equals(destination)) { | 		if (source.equals(destination)) { | ||||||
| 			if (source.isDirectory()) { | 			if (source.isDirectory()) { | ||||||
|  | @ -135,6 +139,45 @@ public class SourceRemapper { | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	private Mercury getMercuryInstance() { | ||||||
|  | 		if (this.mercury != null) { | ||||||
|  | 			return this.mercury; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); | ||||||
|  | 		MappingsProvider mappingsProvider = extension.getMappingsProvider(); | ||||||
|  | 
 | ||||||
|  | 		MappingSet mappings = extension.getOrCreateSrcMappingCache(toNamed ? 1 : 0, () -> { | ||||||
|  | 			try { | ||||||
|  | 				TinyTree m = mappingsProvider.getMappings(); | ||||||
|  | 				project.getLogger().lifecycle(":loading " + (toNamed ? "intermediary -> named" : "named -> intermediary") + " source mappings"); | ||||||
|  | 				return new TinyReader(m, toNamed ? "intermediary" : "named", toNamed ? "named" : "intermediary").read(); | ||||||
|  | 			} catch (Exception e) { | ||||||
|  | 				throw new RuntimeException(e); | ||||||
|  | 			} | ||||||
|  | 		}); | ||||||
|  | 
 | ||||||
|  | 		Mercury mercury = extension.getOrCreateSrcMercuryCache(toNamed ? 1 : 0, () -> { | ||||||
|  | 			Mercury m = createMercuryWithClassPath(project, toNamed); | ||||||
|  | 
 | ||||||
|  | 			for (Path file : extension.getUnmappedMods()) { | ||||||
|  | 				if (Files.isRegularFile(file)) { | ||||||
|  | 					m.getClassPath().add(file); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			m.getClassPath().add(extension.getMinecraftMappedProvider().getMappedJar().toPath()); | ||||||
|  | 			m.getClassPath().add(extension.getMinecraftMappedProvider().getIntermediaryJar().toPath()); | ||||||
|  | 
 | ||||||
|  | 			m.getProcessors().add(MercuryRemapper.create(mappings)); | ||||||
|  | 
 | ||||||
|  | 			return m; | ||||||
|  | 		}); | ||||||
|  | 
 | ||||||
|  | 		this.mercury = mercury; | ||||||
|  | 		return mercury; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	private static void copyNonJavaFiles(Path from, Path to, Project project, File source) throws IOException { | 	private static void copyNonJavaFiles(Path from, Path to, Project project, File source) throws IOException { | ||||||
| 		Files.walk(from).forEach(path -> { | 		Files.walk(from).forEach(path -> { | ||||||
| 			Path targetPath = to.resolve(from.relativize(path).toString()); | 			Path targetPath = to.resolve(from.relativize(path).toString()); | ||||||
|  |  | ||||||
|  | @ -44,6 +44,7 @@ import org.objectweb.asm.ClassWriter; | ||||||
| import org.objectweb.asm.FieldVisitor; | import org.objectweb.asm.FieldVisitor; | ||||||
| import org.objectweb.asm.MethodVisitor; | import org.objectweb.asm.MethodVisitor; | ||||||
| import org.objectweb.asm.Opcodes; | import org.objectweb.asm.Opcodes; | ||||||
|  | import org.objectweb.asm.commons.Remapper; | ||||||
| import org.zeroturnaround.zip.ZipUtil; | import org.zeroturnaround.zip.ZipUtil; | ||||||
| import org.zeroturnaround.zip.transform.ByteArrayZipEntryTransformer; | import org.zeroturnaround.zip.transform.ByteArrayZipEntryTransformer; | ||||||
| import org.zeroturnaround.zip.transform.ZipEntryTransformer; | import org.zeroturnaround.zip.transform.ZipEntryTransformer; | ||||||
|  | @ -53,6 +54,7 @@ import net.fabricmc.mappings.EntryTriple; | ||||||
| import net.fabricmc.loom.LoomGradleExtension; | import net.fabricmc.loom.LoomGradleExtension; | ||||||
| import net.fabricmc.loom.util.Checksum; | import net.fabricmc.loom.util.Checksum; | ||||||
| import net.fabricmc.loom.processors.JarProcessor; | import net.fabricmc.loom.processors.JarProcessor; | ||||||
|  | import net.fabricmc.tinyremapper.TinyRemapper; | ||||||
| 
 | 
 | ||||||
| public class AccessWidenerJarProcessor implements JarProcessor { | public class AccessWidenerJarProcessor implements JarProcessor { | ||||||
| 	private AccessWidener accessWidener = new AccessWidener(); | 	private AccessWidener accessWidener = new AccessWidener(); | ||||||
|  | @ -79,8 +81,13 @@ public class AccessWidenerJarProcessor implements JarProcessor { | ||||||
| 		//Remap accessWidener if its not named, allows for AE's to be written in intermediary | 		//Remap accessWidener if its not named, allows for AE's to be written in intermediary | ||||||
| 		if (!accessWidener.namespace.equals("named")) { | 		if (!accessWidener.namespace.equals("named")) { | ||||||
| 			try { | 			try { | ||||||
| 				AccessWidenerRemapper remapper = new AccessWidenerRemapper(accessWidener, loomGradleExtension.getMappingsProvider().getMappings(), "named"); | 				TinyRemapper tinyRemapper = loomGradleExtension.getMinecraftMappedProvider().getTinyRemapper("official", "named"); | ||||||
|  | 				tinyRemapper.readClassPath(loomGradleExtension.getMinecraftMappedProvider().getRemapClasspath()); | ||||||
|  | 
 | ||||||
|  | 				AccessWidenerRemapper remapper = new AccessWidenerRemapper(accessWidener, tinyRemapper.getRemapper(), "named"); | ||||||
| 				accessWidener = remapper.remap(); | 				accessWidener = remapper.remap(); | ||||||
|  | 
 | ||||||
|  | 				tinyRemapper.finish(); | ||||||
| 			} catch (IOException e) { | 			} catch (IOException e) { | ||||||
| 				throw new RuntimeException("Failed to remap access widener", e); | 				throw new RuntimeException("Failed to remap access widener", e); | ||||||
| 			} | 			} | ||||||
|  | @ -116,9 +123,8 @@ public class AccessWidenerJarProcessor implements JarProcessor { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	//Called when remapping the mod | 	//Called when remapping the mod | ||||||
| 	public void remapAccessWidener(Path modJarPath) throws IOException { | 	public void remapAccessWidener(Path modJarPath, Remapper asmRemapper) throws IOException { | ||||||
| 		LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); | 		AccessWidenerRemapper remapper = new AccessWidenerRemapper(accessWidener, asmRemapper, "intermediary"); | ||||||
| 		AccessWidenerRemapper remapper = new AccessWidenerRemapper(accessWidener, extension.getMappingsProvider().getMappings(), "intermediary"); |  | ||||||
| 		AccessWidener remapped = remapper.remap(); | 		AccessWidener remapped = remapper.remap(); | ||||||
| 
 | 
 | ||||||
| 		StringWriter writer = new StringWriter(); | 		StringWriter writer = new StringWriter(); | ||||||
|  |  | ||||||
|  | @ -24,54 +24,21 @@ | ||||||
| 
 | 
 | ||||||
| package net.fabricmc.loom.util.accesswidener; | package net.fabricmc.loom.util.accesswidener; | ||||||
| 
 | 
 | ||||||
| import java.util.HashMap; |  | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
| 
 | 
 | ||||||
| import net.fabricmc.mapping.tree.ClassDef; | import org.objectweb.asm.commons.Remapper; | ||||||
| import net.fabricmc.mapping.tree.FieldDef; | 
 | ||||||
| import net.fabricmc.mapping.tree.MethodDef; |  | ||||||
| import net.fabricmc.mapping.tree.TinyTree; |  | ||||||
| import net.fabricmc.mappings.EntryTriple; | import net.fabricmc.mappings.EntryTriple; | ||||||
| 
 | 
 | ||||||
| public class AccessWidenerRemapper { | public class AccessWidenerRemapper { | ||||||
| 	private final AccessWidener input; | 	private final AccessWidener input; | ||||||
| 	private final String from, to; | 	private final String to; | ||||||
|  | 	private final Remapper remapper; | ||||||
| 
 | 
 | ||||||
| 	private Map<String, String> classNames = new HashMap<>(); | 	public AccessWidenerRemapper(AccessWidener input, Remapper remapper, String to) { | ||||||
| 	private Map<EntryTriple, EntryTriple> fieldNames = new HashMap<>(); |  | ||||||
| 	private Map<EntryTriple, EntryTriple> methodNames = new HashMap<>(); |  | ||||||
| 
 |  | ||||||
| 	public AccessWidenerRemapper(AccessWidener input, TinyTree tinyTree, String to) { |  | ||||||
| 		this.input = input; | 		this.input = input; | ||||||
| 		this.from = input.namespace; |  | ||||||
| 		this.to = to; | 		this.to = to; | ||||||
| 		populateMappings(tinyTree); | 		this.remapper = remapper; | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	private void populateMappings(TinyTree tinyTree) { |  | ||||||
| 		if (!tinyTree.getMetadata().getNamespaces().contains(from)) { |  | ||||||
| 			throw new UnsupportedOperationException("Unknown namespace: " + from); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (!tinyTree.getMetadata().getNamespaces().contains(to)) { |  | ||||||
| 			throw new UnsupportedOperationException("Unknown namespace: " + to); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		for (ClassDef classDef : tinyTree.getClasses()) { |  | ||||||
| 			classNames.put(classDef.getName(from), classDef.getName(to)); |  | ||||||
| 
 |  | ||||||
| 			for (FieldDef fieldDef : classDef.getFields()) { |  | ||||||
| 				EntryTriple fromEntry = new EntryTriple(classDef.getName(from), fieldDef.getName(from), fieldDef.getDescriptor(from)); |  | ||||||
| 				EntryTriple toEntry = new EntryTriple(classDef.getName(to), fieldDef.getName(to), fieldDef.getDescriptor(to)); |  | ||||||
| 				fieldNames.put(fromEntry, toEntry); |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			for (MethodDef methodDef : classDef.getMethods()) { |  | ||||||
| 				EntryTriple fromEntry = new EntryTriple(classDef.getName(from), methodDef.getName(from), methodDef.getDescriptor(from)); |  | ||||||
| 				EntryTriple toEntry = new EntryTriple(classDef.getName(to), methodDef.getName(to), methodDef.getDescriptor(to)); |  | ||||||
| 				methodNames.put(fromEntry, toEntry); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public AccessWidener remap() { | 	public AccessWidener remap() { | ||||||
|  | @ -84,27 +51,33 @@ public class AccessWidenerRemapper { | ||||||
| 		remapped.namespace = to; | 		remapped.namespace = to; | ||||||
| 
 | 
 | ||||||
| 		for (Map.Entry<String, AccessWidener.Access> entry : input.classAccess.entrySet()) { | 		for (Map.Entry<String, AccessWidener.Access> entry : input.classAccess.entrySet()) { | ||||||
| 			remapped.classAccess.put(findMapping(classNames, entry.getKey()), entry.getValue()); | 			remapped.classAccess.put(remapper.map(entry.getKey()), entry.getValue()); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		for (Map.Entry<EntryTriple, AccessWidener.Access> entry : input.methodAccess.entrySet()) { | 		for (Map.Entry<EntryTriple, AccessWidener.Access> entry : input.methodAccess.entrySet()) { | ||||||
| 			remapped.addOrMerge(remapped.methodAccess, findMapping(methodNames, entry.getKey()), entry.getValue()); | 			remapped.addOrMerge(remapped.methodAccess, remapMethod(entry.getKey()), entry.getValue()); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		for (Map.Entry<EntryTriple, AccessWidener.Access> entry : input.fieldAccess.entrySet()) { | 		for (Map.Entry<EntryTriple, AccessWidener.Access> entry : input.fieldAccess.entrySet()) { | ||||||
| 			remapped.addOrMerge(remapped.fieldAccess, findMapping(fieldNames, entry.getKey()), entry.getValue()); | 			remapped.addOrMerge(remapped.fieldAccess, remapField(entry.getKey()), entry.getValue()); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return remapped; | 		return remapped; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private static <K, V> V findMapping(Map<K, V> map, K key) { | 	private EntryTriple remapMethod(EntryTriple entryTriple) { | ||||||
| 		V value = map.get(key); | 		return new EntryTriple( | ||||||
|  | 					remapper.map(entryTriple.getName()), | ||||||
|  | 					remapper.mapMethodName(entryTriple.getOwner(), entryTriple.getName(), entryTriple.getDesc()), | ||||||
|  | 					remapper.mapDesc(entryTriple.getDesc()) | ||||||
|  | 				); | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 		if (value == null) { | 	private EntryTriple remapField(EntryTriple entryTriple) { | ||||||
| 			throw new RuntimeException("Failed to find mapping for " + key.toString()); | 		return new EntryTriple( | ||||||
| 		} | 				remapper.map(entryTriple.getName()), | ||||||
| 
 | 				remapper.mapFieldName(entryTriple.getOwner(), entryTriple.getName(), entryTriple.getDesc()), | ||||||
| 		return value; | 				remapper.mapDesc(entryTriple.getDesc()) | ||||||
|  | 		); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue