aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFudge <natan.lifsiz@gmail.com>2019-11-09 21:00:36 +0200
committerPlayer <sfPlayer1@users.noreply.github.com>2019-11-09 19:00:36 +0000
commit8e916f8fb0523ee3a516f0b5a2606d344dd0b414 (patch)
tree04c8adbd380a44b6aaa234c6f4f8fbe472cadaa8
parentbaf976d3f3697c8a184fea14671079fa7ee4c9f8 (diff)
downloadarchitectury-loom-8e916f8fb0523ee3a516f0b5a2606d344dd0b414.tar.gz
architectury-loom-8e916f8fb0523ee3a516f0b5a2606d344dd0b414.tar.bz2
architectury-loom-8e916f8fb0523ee3a516f0b5a2606d344dd0b414.zip
Support using TinyV2 mappings (#132)
-rw-r--r--build.gradle13
-rw-r--r--src/main/java/net/fabricmc/loom/AbstractPlugin.java13
-rw-r--r--src/main/java/net/fabricmc/loom/providers/MappingsCache.java18
-rw-r--r--src/main/java/net/fabricmc/loom/providers/MappingsProvider.java203
-rw-r--r--src/main/java/net/fabricmc/loom/providers/MinecraftMappedProvider.java28
-rw-r--r--src/main/java/net/fabricmc/loom/task/CleanLoomMappings.java12
-rw-r--r--src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java206
-rw-r--r--src/main/java/net/fabricmc/loom/task/RemapJarTask.java6
-rw-r--r--src/main/java/net/fabricmc/loom/util/Constants.java1
-rw-r--r--src/main/java/net/fabricmc/loom/util/MapJarsTiny.java8
-rw-r--r--src/main/java/net/fabricmc/loom/util/ModProcessor.java15
-rw-r--r--src/main/java/net/fabricmc/loom/util/SourceRemapper.java75
-rw-r--r--src/main/java/net/fabricmc/loom/util/TinyRemapperMappingsHelper.java52
-rw-r--r--src/test/groovy/net/fabricmc/loom/BuildUtils.groovy1
-rw-r--r--src/test/groovy/net/fabricmc/loom/EmptyBuildFunctionalTest.groovy2
-rw-r--r--src/test/groovy/net/fabricmc/loom/SimpleBuildFunctionalTest.groovy4
16 files changed, 447 insertions, 210 deletions
diff --git a/build.gradle b/build.gradle
index 90fe3c3d..7992cd8a 100644
--- a/build.gradle
+++ b/build.gradle
@@ -39,15 +39,17 @@ dependencies {
implementation ('com.google.guava:guava:28.0-jre')
// game handling utils
- implementation ('net.fabricmc:stitch:0.2.1.60') {
+ implementation ('net.fabricmc:stitch:0.3.0.66') {
exclude module: 'enigma'
}
// tinyfile management
- implementation ('net.fabricmc:tiny-remapper:0.1.0.38') {
+ implementation ('net.fabricmc:tiny-remapper:0.2.0.52') {
transitive = false
}
- implementation ('net.fabricmc:fabric-mixin-compile-extensions:0.1.0.+')
+ implementation ('net.fabricmc:fabric-mixin-compile-extensions:0.2.0.3'){
+ exclude group :"net.fabricmc"
+ }
// decompilers
implementation ('net.fabricmc:procyon-fabric-compilertools:0.5.35.+')
@@ -132,3 +134,8 @@ publishing {
}
}
}
+configurations.all {
+ resolutionStrategy {
+ force 'org.codehaus.groovy:groovy-all:2.4.12'
+ }
+}
diff --git a/src/main/java/net/fabricmc/loom/AbstractPlugin.java b/src/main/java/net/fabricmc/loom/AbstractPlugin.java
index ceb31bdf..88e135a3 100644
--- a/src/main/java/net/fabricmc/loom/AbstractPlugin.java
+++ b/src/main/java/net/fabricmc/loom/AbstractPlugin.java
@@ -114,6 +114,7 @@ public class AbstractPlugin implements Plugin<Project> {
includeConfig.setTransitive(false); // Dont get transitive deps
project.getConfigurations().maybeCreate(Constants.MAPPINGS);
+ project.getConfigurations().maybeCreate(Constants.MAPPINGS_FINAL);
for (RemappedConfigurationEntry entry : Constants.MOD_COMPILE_ENTRIES) {
Configuration compileModsConfig = project.getConfigurations().maybeCreate(entry.getSourceConfiguration());
@@ -136,8 +137,8 @@ public class AbstractPlugin implements Plugin<Project> {
extendsFrom(Constants.MINECRAFT_NAMED, Constants.MINECRAFT_DEPENDENCIES);
extendsFrom(Constants.MINECRAFT_INTERMEDIARY, Constants.MINECRAFT_DEPENDENCIES);
- extendsFrom("compile", Constants.MAPPINGS);
- extendsFrom("annotationProcessor", Constants.MAPPINGS);
+ extendsFrom("compile", Constants.MAPPINGS_FINAL);
+ extendsFrom("annotationProcessor", Constants.MAPPINGS_FINAL);
configureIDEs();
configureCompile();
@@ -156,8 +157,8 @@ public class AbstractPlugin implements Plugin<Project> {
project.getLogger().lifecycle(":setting java compiler args");
try {
- javaCompileTask.getOptions().getCompilerArgs().add("-AinMapFileNamedIntermediary=" + extension.getMappingsProvider().MAPPINGS_TINY.getCanonicalPath());
- javaCompileTask.getOptions().getCompilerArgs().add("-AoutMapFileNamedIntermediary=" + extension.getMappingsProvider().MAPPINGS_MIXIN_EXPORT.getCanonicalPath());
+ javaCompileTask.getOptions().getCompilerArgs().add("-AinMapFileNamedIntermediary=" + extension.getMappingsProvider().tinyMappings.getCanonicalPath());
+ javaCompileTask.getOptions().getCompilerArgs().add("-AoutMapFileNamedIntermediary=" + extension.getMappingsProvider().mappingsMixinExport.getCanonicalPath());
javaCompileTask.getOptions().getCompilerArgs().add("-AoutRefMapFile=" + new File(javaCompileTask.getDestinationDir(), extension.getRefmapName()).getCanonicalPath());
javaCompileTask.getOptions().getCompilerArgs().add("-AdefaultObfuscationEnv=named:intermediary");
} catch (IOException e) {
@@ -183,8 +184,8 @@ public class AbstractPlugin implements Plugin<Project> {
project.getLogger().warn(":configuring scala compilation processing");
try {
- task.getOptions().getCompilerArgs().add("-AinMapFileNamedIntermediary=" + extension.getMappingsProvider().MAPPINGS_TINY.getCanonicalPath());
- task.getOptions().getCompilerArgs().add("-AoutMapFileNamedIntermediary=" + extension.getMappingsProvider().MAPPINGS_MIXIN_EXPORT.getCanonicalPath());
+ task.getOptions().getCompilerArgs().add("-AinMapFileNamedIntermediary=" + extension.getMappingsProvider().tinyMappings.getCanonicalPath());
+ task.getOptions().getCompilerArgs().add("-AoutMapFileNamedIntermediary=" + extension.getMappingsProvider().mappingsMixinExport.getCanonicalPath());
task.getOptions().getCompilerArgs().add("-AoutRefMapFile=" + new File(task.getDestinationDir(), extension.getRefmapName()).getCanonicalPath());
task.getOptions().getCompilerArgs().add("-AdefaultObfuscationEnv=named:intermediary");
} catch (IOException e) {
diff --git a/src/main/java/net/fabricmc/loom/providers/MappingsCache.java b/src/main/java/net/fabricmc/loom/providers/MappingsCache.java
index 953f6940..fbcec82f 100644
--- a/src/main/java/net/fabricmc/loom/providers/MappingsCache.java
+++ b/src/main/java/net/fabricmc/loom/providers/MappingsCache.java
@@ -24,8 +24,8 @@
package net.fabricmc.loom.providers;
+import java.io.BufferedReader;
import java.io.IOException;
-import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -33,32 +33,32 @@ import java.util.HashMap;
import java.util.Map;
import net.fabricmc.loom.util.StaticPathWatcher;
-import net.fabricmc.mappings.Mappings;
+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<Mappings>> mappingsCache = new HashMap<>();
+ private final Map<Path, SoftReference<TinyTree>> mappingsCache = new HashMap<>();
- public Mappings get(Path mappingsPath) {
+ //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<Mappings> ref = mappingsCache.get(mappingsPath);
+ SoftReference<TinyTree> ref = mappingsCache.get(mappingsPath);
if (ref != null && ref.get() != null) {
return ref.get();
} else {
- try (InputStream stream = Files.newInputStream(mappingsPath)) {
- Mappings mappings = net.fabricmc.mappings.MappingsProvider.readTinyMappings(stream, false);
+ try (BufferedReader reader = Files.newBufferedReader(mappingsPath)) {
+ TinyTree mappings = TinyMappingFactory.loadWithDetection(reader);
ref = new SoftReference<>(mappings);
mappingsCache.put(mappingsPath, ref);
return mappings;
- } catch (IOException e) {
- throw new RuntimeException(e);
}
}
}
diff --git a/src/main/java/net/fabricmc/loom/providers/MappingsProvider.java b/src/main/java/net/fabricmc/loom/providers/MappingsProvider.java
index 3eddfc54..77f8d153 100644
--- a/src/main/java/net/fabricmc/loom/providers/MappingsProvider.java
+++ b/src/main/java/net/fabricmc/loom/providers/MappingsProvider.java
@@ -24,25 +24,38 @@
package net.fabricmc.loom.providers;
+import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
+import java.net.URL;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
import java.util.function.Consumer;
+import com.google.common.net.UrlEscapers;
+import org.apache.commons.io.FileUtils;
+import org.apache.tools.ant.util.StringUtils;
import org.gradle.api.Project;
+import org.zeroturnaround.zip.FileSource;
+import org.zeroturnaround.zip.ZipEntrySource;
+import org.zeroturnaround.zip.ZipUtil;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.util.Constants;
import net.fabricmc.loom.util.DependencyProvider;
+import net.fabricmc.loom.util.DownloadUtil;
import net.fabricmc.loom.util.Version;
-import net.fabricmc.mappings.Mappings;
+import net.fabricmc.mapping.reader.v2.TinyV2Factory;
+import net.fabricmc.mapping.tree.TinyTree;
+import net.fabricmc.stitch.Command;
import net.fabricmc.stitch.commands.CommandProposeFieldNames;
+import net.fabricmc.stitch.commands.tinyv2.CommandMergeTinyV2;
+import net.fabricmc.stitch.commands.tinyv2.CommandReorderTinyV2;
-//TODO fix local mappings
-//TODO possibly use maven for mappings, can fix above at the same time
public class MappingsProvider extends DependencyProvider {
public MinecraftMappedProvider mappedProvider;
@@ -50,13 +63,21 @@ public class MappingsProvider extends DependencyProvider {
public String minecraftVersion;
public String mappingsVersion;
- public File MAPPINGS_DIR;
- public File MAPPINGS_TINY_BASE;
- public File MAPPINGS_TINY;
- public File MAPPINGS_MIXIN_EXPORT;
+ private Path mappingsDir;
+ private Path mappingsStepsDir;
+ // The mappings that gradle gives us
+ private Path baseTinyMappings;
+ // The mappings we use in practice
+ public File tinyMappings;
+ public File tinyMappingsJar;
+ public File mappingsMixinExport;
- public Mappings getMappings() throws IOException {
- return MappingsCache.INSTANCE.get(MAPPINGS_TINY.toPath());
+ public void clean() throws IOException {
+ FileUtils.deleteDirectory(mappingsDir.toFile());
+ }
+
+ public TinyTree getMappings() throws IOException {
+ return MappingsCache.INSTANCE.get(tinyMappings.toPath());
}
@Override
@@ -66,50 +87,166 @@ public class MappingsProvider extends DependencyProvider {
project.getLogger().lifecycle(":setting up mappings (" + dependency.getDependency().getName() + " " + dependency.getResolvedVersion() + ")");
String version = dependency.getResolvedVersion();
- File mappingsJar = dependency.resolveFile().orElseThrow(() -> new RuntimeException("Could not find dependency " + dependency));
+ File mappingsJar = dependency.resolveFile().orElseThrow(() -> new RuntimeException("Could not find yarn mappings: " + dependency));
- this.mappingsName = dependency.getDependency().getGroup() + "." + dependency.getDependency().getName();
+ this.mappingsName = StringUtils.removeSuffix(dependency.getDependency().getGroup() + "." + dependency.getDependency().getName(), "-unmerged");
+
+ boolean isV2 = doesJarContainV2Mappings(mappingsJar.toPath());
Version mappingsVersion = new Version(version);
this.minecraftVersion = mappingsVersion.getMinecraftVersion();
- this.mappingsVersion = mappingsVersion.getMappingsVersion();
+ this.mappingsVersion = mappingsVersion.getMappingsVersion() + (isV2 ? "-v2" : "");
initFiles(project);
- if (!MAPPINGS_DIR.exists()) {
- MAPPINGS_DIR.mkdir();
- }
+ Files.createDirectories(mappingsDir);
+ Files.createDirectories(mappingsStepsDir);
- if (!MAPPINGS_TINY_BASE.exists() || !MAPPINGS_TINY.exists()) {
- if (!MAPPINGS_TINY_BASE.exists()) {
- project.getLogger().lifecycle(":extracting " + mappingsJar.getName());
+ String[] depStringSplit = dependency.getDepString().split(":");
+ String jarClassifier = "final";
- try (FileSystem fileSystem = FileSystems.newFileSystem(mappingsJar.toPath(), null)) {
- Path fileToExtract = fileSystem.getPath("mappings/mappings.tiny");
- Files.copy(fileToExtract, MAPPINGS_TINY_BASE.toPath());
- }
- }
+ if (depStringSplit.length >= 4) {
+ jarClassifier = jarClassifier + depStringSplit[3];
+ }
- if (MAPPINGS_TINY.exists()) {
- MAPPINGS_TINY.delete();
- }
+ tinyMappings = mappingsDir.resolve(StringUtils.removeSuffix(mappingsJar.getName(), ".jar") + ".tiny").toFile();
+ tinyMappingsJar = new File(extension.getUserCache(), mappingsJar.getName().replace(".jar", "-" + jarClassifier + ".jar"));
- project.getLogger().lifecycle(":populating field names");
- new CommandProposeFieldNames().run(new String[]{minecraftProvider.MINECRAFT_MERGED_JAR.getAbsolutePath(), MAPPINGS_TINY_BASE.getAbsolutePath(), MAPPINGS_TINY.getAbsolutePath()});
+ if (!tinyMappings.exists()) {
+ storeMappings(project, minecraftProvider, mappingsJar.toPath());
+ }
+
+ if (!tinyMappingsJar.exists()) {
+ ZipUtil.pack(new ZipEntrySource[] {new FileSource("mappings/mappings.tiny", tinyMappings)}, tinyMappingsJar);
}
+ addDependency(tinyMappingsJar, project, Constants.MAPPINGS_FINAL);
+
mappedProvider = new MinecraftMappedProvider();
mappedProvider.initFiles(project, minecraftProvider, this);
mappedProvider.provide(dependency, project, extension, postPopulationScheduler);
}
- public void initFiles(Project project) {
+ private void storeMappings(Project project, MinecraftProvider minecraftProvider, Path yarnJar) throws IOException {
+ project.getLogger().lifecycle(":extracting " + yarnJar.getFileName());
+
+ try (FileSystem fileSystem = FileSystems.newFileSystem(yarnJar, null)) {
+ extractMappings(fileSystem, baseTinyMappings);
+ }
+
+ if (baseMappingsAreV2()) {
+ // These are unmerged v2 mappings
+
+ // Download and extract intermediary
+ String encodedMinecraftVersion = UrlEscapers.urlFragmentEscaper().escape(minecraftVersion);
+ String intermediaryArtifactUrl = "https://maven.fabricmc.net/net/fabricmc/intermediary/" + encodedMinecraftVersion + "/intermediary-" + encodedMinecraftVersion + "-v2.jar";
+ Path intermediaryJar = mappingsStepsDir.resolve("v2-intermediary-" + minecraftVersion + ".jar");
+ DownloadUtil.downloadIfChanged(new URL(intermediaryArtifactUrl), intermediaryJar.toFile(), project.getLogger());
+
+ mergeAndSaveMappings(project, intermediaryJar, yarnJar);
+ } else {
+ // These are merged v1 mappings
+ if (tinyMappings.exists()) {
+ tinyMappings.delete();
+ }
+
+ project.getLogger().lifecycle(":populating field names");
+ suggestFieldNames(minecraftProvider, baseTinyMappings, tinyMappings.toPath());
+ }
+ }
+
+ private boolean baseMappingsAreV2() throws IOException {
+ try (BufferedReader reader = Files.newBufferedReader(baseTinyMappings)) {
+ TinyV2Factory.readMetadata(reader);
+ return true;
+ } catch (IllegalArgumentException e) {
+ // TODO: just check the mappings version when Parser supports V1 in readMetadata()
+ return false;
+ }
+ }
+
+ private boolean doesJarContainV2Mappings(Path path) throws IOException {
+ try (FileSystem fs = FileSystems.newFileSystem(path, null)) {
+ try (BufferedReader reader = Files.newBufferedReader(fs.getPath("mappings", "mappings.tiny"))) {
+ TinyV2Factory.readMetadata(reader);
+ return true;
+ } catch (IllegalArgumentException e) {
+ return false;
+ }
+ }
+ }
+
+ public static void extractMappings(FileSystem jar, Path extractTo) throws IOException {
+ Files.copy(jar.getPath("mappings/mappings.tiny"), extractTo, StandardCopyOption.REPLACE_EXISTING);
+ }
+
+ private void mergeAndSaveMappings(Project project, Path unmergedIntermediaryJar, Path unmergedYarnJar) throws IOException {
+ Path unmergedIntermediary = Paths.get(mappingsStepsDir.toString(), "unmerged-intermediary.tiny");
+ project.getLogger().info(":extracting " + unmergedIntermediaryJar.getFileName());
+
+ try (FileSystem unmergedIntermediaryFs = FileSystems.newFileSystem(unmergedIntermediaryJar, null)) {
+ extractMappings(unmergedIntermediaryFs, unmergedIntermediary);
+ }
+
+ Path unmergedYarn = Paths.get(mappingsStepsDir.toString(), "unmerged-yarn.tiny");
+ project.getLogger().info(":extracting " + unmergedYarnJar.getFileName());
+
+ try (FileSystem unmergedYarnJarFs = FileSystems.newFileSystem(unmergedYarnJar, null)) {
+ extractMappings(unmergedYarnJarFs, unmergedYarn);
+ }
+
+ Path invertedIntermediary = Paths.get(mappingsStepsDir.toString(), "inverted-intermediary.tiny");
+ reorderMappings(unmergedIntermediary, invertedIntermediary, "intermediary", "official");
+ Path unorderedMergedMappings = Paths.get(mappingsStepsDir.toString(), "unordered-merged.tiny");
+ project.getLogger().info(":merging");
+ mergeMappings(invertedIntermediary, unmergedYarn, unorderedMergedMappings);
+ reorderMappings(unorderedMergedMappings, tinyMappings.toPath(), "official", "intermediary", "named");
+ }
+
+ private void reorderMappings(Path oldMappings, Path newMappings, String... newOrder) {
+ Command command = new CommandReorderTinyV2();
+ String[] args = new String[2 + newOrder.length];
+ args[0] = oldMappings.toAbsolutePath().toString();
+ args[1] = newMappings.toAbsolutePath().toString();
+ System.arraycopy(newOrder, 0, args, 2, newOrder.length);
+ runCommand(command, args);
+ }
+
+ private void mergeMappings(Path intermediaryMappings, Path yarnMappings, Path newMergedMappings) {
+ try {
+ Command command = new CommandMergeTinyV2();
+ runCommand(command, intermediaryMappings.toAbsolutePath().toString(),
+ yarnMappings.toAbsolutePath().toString(),
+ newMergedMappings.toAbsolutePath().toString(),
+ "intermediary", "official");
+ } catch (Exception e) {
+ throw new RuntimeException("Could not merge mappings from " + intermediaryMappings.toString()
+ + " with mappings from " + yarnMappings, e);
+ }
+ }
+
+ private void suggestFieldNames(MinecraftProvider minecraftProvider, Path oldMappings, Path newMappings) {
+ Command command = new CommandProposeFieldNames();
+ runCommand(command, minecraftProvider.MINECRAFT_MERGED_JAR.getAbsolutePath(),
+ oldMappings.toAbsolutePath().toString(),
+ newMappings.toAbsolutePath().toString());
+ }
+
+ private void runCommand(Command command, String... args) {
+ try {
+ command.run(args);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private void initFiles(Project project) {
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
- MAPPINGS_DIR = new File(extension.getUserCache(), "mappings");
+ mappingsDir = extension.getUserCache().toPath().resolve("mappings");
+ mappingsStepsDir = mappingsDir.resolve("steps");
- MAPPINGS_TINY_BASE = new File(MAPPINGS_DIR, mappingsName + "-tiny-" + minecraftVersion + "-" + mappingsVersion + "-base");
- MAPPINGS_TINY = new File(MAPPINGS_DIR, mappingsName + "-tiny-" + minecraftVersion + "-" + mappingsVersion);
- MAPPINGS_MIXIN_EXPORT = new File(extension.getProjectBuildCache(), "mixin-map-" + minecraftVersion + "-" + mappingsVersion + ".tiny");
+ baseTinyMappings = mappingsDir.resolve(mappingsName + "-tiny-" + minecraftVersion + "-" + mappingsVersion + "-base");
+ mappingsMixinExport = new File(extension.getProjectBuildCache(), "mixin-map-" + minecraftVersion + "-" + mappingsVersion + ".tiny");
}
@Override
diff --git a/src/main/java/net/fabricmc/loom/providers/MinecraftMappedProvider.java b/src/main/java/net/fabricmc/loom/providers/MinecraftMappedProvider.java
index 9d44c0d1..3a398a86 100644
--- a/src/main/java/net/fabricmc/loom/providers/MinecraftMappedProvider.java
+++ b/src/main/java/net/fabricmc/loom/providers/MinecraftMappedProvider.java
@@ -39,11 +39,14 @@ public class MinecraftMappedProvider extends DependencyProvider {
public File MINECRAFT_MAPPED_JAR;
public File MINECRAFT_INTERMEDIARY_JAR;
+ public MinecraftMappedProvider() {
+ }
+
private MinecraftProvider minecraftProvider;
@Override
public void provide(DependencyInfo dependency, Project project, LoomGradleExtension extension, Consumer<Runnable> postPopulationScheduler) throws Exception {
- if (!extension.getMappingsProvider().MAPPINGS_TINY.exists()) {
+ if (!extension.getMappingsProvider().tinyMappings.exists()) {
throw new RuntimeException("mappings file not found");
}
@@ -67,17 +70,28 @@ public class MinecraftMappedProvider extends DependencyProvider {
throw new RuntimeException("mapped jar not found");
}
- String version = minecraftProvider.minecraftVersion + "-mapped-" + extension.getMappingsProvider().mappingsName + "-" + extension.getMappingsProvider().mappingsVersion;
- project.getDependencies().add(Constants.MINECRAFT_NAMED, project.getDependencies().module("net.minecraft:minecraft:" + version));
- version = minecraftProvider.minecraftVersion + "-intermediary-" + extension.getMappingsProvider().mappingsName;
- project.getDependencies().add(Constants.MINECRAFT_INTERMEDIARY, project.getDependencies().module("net.minecraft:minecraft:" + version));
+ MappingsProvider mappingsProvider = extension.getMappingsProvider();
+ project.getDependencies().add(Constants.MINECRAFT_NAMED,
+ project.getDependencies().module("net.minecraft:minecraft:" + getNamedJarVersionString(mappingsProvider.mappingsName, mappingsProvider.mappingsVersion)));
+ project.getDependencies().add(Constants.MINECRAFT_INTERMEDIARY,
+ project.getDependencies().module("net.minecraft:minecraft:" + getIntermediaryJarVersionString(mappingsProvider.mappingsName, mappingsProvider.mappingsVersion)));
}
public void initFiles(Project project, MinecraftProvider minecraftProvider, MappingsProvider mappingsProvider) {
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
this.minecraftProvider = minecraftProvider;
- MINECRAFT_INTERMEDIARY_JAR = new File(extension.getUserCache(), "minecraft-" + minecraftProvider.minecraftVersion + "-intermediary-" + mappingsProvider.mappingsName + ".jar");
- MINECRAFT_MAPPED_JAR = new File(extension.getUserCache(), "minecraft-" + minecraftProvider.minecraftVersion + "-mapped-" + mappingsProvider.mappingsName + "-" + mappingsProvider.mappingsVersion + ".jar");
+ MINECRAFT_INTERMEDIARY_JAR = new File(extension.getUserCache(),
+ "minecraft-" + getIntermediaryJarVersionString(mappingsProvider.mappingsName, mappingsProvider.mappingsVersion) + ".jar");
+ MINECRAFT_MAPPED_JAR = new File(extension.getUserCache(),
+ "minecraft-" + getNamedJarVersionString(mappingsProvider.mappingsName, mappingsProvider.mappingsVersion) + ".jar");
+ }
+
+ private String getNamedJarVersionString(String mappingsName, String mappingsVersion) {
+ return minecraftProvider.minecraftVersion + "-mapped-" + mappingsName + "-" + mappingsVersion;
+ }
+
+ private String getIntermediaryJarVersionString(String mappingsName, String mappingsVersion) {
+ return minecraftProvider.minecraftVersion + "-intermediary-" + mappingsName + "-" + mappingsVersion;
}
public Collection<File> getMapperPaths() {
diff --git a/src/main/java/net/fabricmc/loom/task/CleanLoomMappings.java b/src/main/java/net/fabricmc/loom/task/CleanLoomMappings.java
index f2121b63..2310a8a1 100644
--- a/src/main/java/net/fabricmc/loom/task/CleanLoomMappings.java
+++ b/src/main/java/net/fabricmc/loom/task/CleanLoomMappings.java
@@ -36,14 +36,12 @@ import net.fabricmc.loom.util.DeletingFileVisitor;
public class CleanLoomMappings extends AbstractLoomTask {
@TaskAction
public void run() {
- Project project = this.getProject();
- LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
- extension.getMappingsProvider().MAPPINGS_TINY.delete();
- extension.getMappingsProvider().MAPPINGS_TINY_BASE.delete();
- extension.getMinecraftMappedProvider().getIntermediaryJar().delete();
- extension.getMinecraftMappedProvider().getMappedJar().delete();
-
try {
+ Project project = this.getProject();
+ LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
+ extension.getMappingsProvider().clean();
+ extension.getMinecraftMappedProvider().getIntermediaryJar().delete();
+ extension.getMinecraftMappedProvider().getMappedJar().delete();
Files.walkFileTree(extension.getRootProjectBuildCache().toPath(), new DeletingFileVisitor());
} catch (IOException e) {
throw new RuntimeException(e);
diff --git a/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java b/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java
index 35ef0714..b9657707 100644
--- a/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java
+++ b/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java
@@ -24,27 +24,41 @@
package net.fabricmc.loom.task;
+import java.io.BufferedReader;
import java.io.File;
-import java.io.FileInputStream;
import java.io.IOException;
+import java.net.URL;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
+import java.util.function.BiFunction;
+import com.google.common.net.UrlEscapers;
+import org.apache.commons.io.FileUtils;
import org.cadixdev.lorenz.MappingSet;
import org.cadixdev.lorenz.io.MappingsReader;
+import org.cadixdev.lorenz.model.ClassMapping;
+import org.cadixdev.lorenz.model.Mapping;
import org.cadixdev.mercury.Mercury;
import org.cadixdev.mercury.remapper.MercuryRemapper;
import org.gradle.api.Project;
import org.gradle.api.tasks.TaskAction;
import net.fabricmc.loom.LoomGradleExtension;
-import net.fabricmc.loom.util.Constants;
-import net.fabricmc.loom.util.Version;
-import net.fabricmc.mappings.ClassEntry;
-import net.fabricmc.mappings.EntryTriple;
-import net.fabricmc.mappings.FieldEntry;
-import net.fabricmc.mappings.Mappings;
-import net.fabricmc.mappings.MethodEntry;
+import net.fabricmc.loom.providers.MappingsProvider;
+import net.fabricmc.loom.providers.MinecraftMappedProvider;
+import net.fabricmc.loom.util.SourceRemapper;
+import net.fabricmc.mapping.tree.ClassDef;
+import net.fabricmc.mapping.tree.Descriptored;
+import net.fabricmc.mapping.tree.FieldDef;
+import net.fabricmc.mapping.tree.MethodDef;
+import net.fabricmc.mapping.tree.TinyMappingFactory;
+import net.fabricmc.mapping.tree.TinyTree;
public class MigrateMappingsTask extends AbstractLoomTask {
@TaskAction
@@ -55,75 +69,95 @@ public class MigrateMappingsTask extends AbstractLoomTask {
project.getLogger().lifecycle(":loading mappings");
- File mappingsFile = null;
+ String inputDir = (String) properties.get("inputDir");
+ if (inputDir == null) inputDir = "src/main/java";
+ String outputDir = (String) properties.get("outputDir");
+ if (outputDir == null) outputDir = "remappedSrc";
+ String officialMappingsVersion = (String) properties.get("targetMappings");
+ String localMappingsPath = (String) properties.get("targetLocalMappings");
+
+ if (officialMappingsVersion != null && localMappingsPath != null) {
+ throw new IllegalArgumentException("targetMappings and targetLocalMappings are mutually exclusive;"
+ + " you either specify an official yarn mappings version with targetMappings, "
+ + "or a local one with targetLocalMappings.");
+ }
- if (properties.containsKey("targetMappingsFile")) {
- mappingsFile = new File((String) properties.get("targetMappingsFile"));
- } else if (properties.containsKey("targetMappingsArtifact")) {
- String[] artifactName = ((String) properties.get("targetMappingsArtifact")).split(":");
+ if (officialMappingsVersion == null && localMappingsPath == null) {
+ throw new IllegalArgumentException("You must specify a new mappings version with -PtargetMappings (or local mappings with -PtargetLocalMappings).");
+ }
- if (artifactName.length != 3) {
- throw new RuntimeException("Invalid artifact name: " + properties.get("targetMappingsArtifact"));
- }
+ boolean useLocalMappings = localMappingsPath != null;
- String mappingsName = artifactName[0] + "." + artifactName[1];
+ if (useLocalMappings && !Files.exists(Paths.get(localMappingsPath))) {
+ throw new IllegalArgumentException("Can't find local mappings in specified location: " + localMappingsPath);
+ }
- Version v = new Version(artifactName[2]);
- String minecraftVersion = v.getMinecraftVersion();
- String mappingsVersion = v.getMappingsVersion();
+ String targetMappingsName = useLocalMappings ? localMappingsPath : officialMappingsVersion;
- mappingsFile = new File(extension.getMappingsProvider().MAPPINGS_DIR, mappingsName + "-tiny-" + minecraftVersion + "-" + mappingsVersion);
- }
+ Path inputDirPath = Paths.get(System.getProperty("user.dir"), inputDir);
+ Path outputDirPath = Paths.get(System.getProperty("user.dir"), outputDir);
- if (mappingsFile == null || !mappingsFile.exists()) {
- throw new RuntimeException("Could not find mappings file: " + (mappingsFile != null ? mappingsFile : "null"));
+ if (!Files.exists(inputDirPath) || !Files.isDirectory(inputDirPath)) {
+ throw new IllegalArgumentException("Could not find input directory: " + inputDirPath.toAbsolutePath());
}
- if (!properties.containsKey("inputDir") || !properties.containsKey("outputDir")) {
- throw new RuntimeException("Must specify input and output dir!");
- }
+ Files.createDirectories(outputDirPath);
- File inputDir = new File((String) properties.get("inputDir"));
- File outputDir = new File((String) properties.get("outputDir"));
+ MappingsProvider mappingsProvider = extension.getMappingsProvider();
- if (!inputDir.exists() || !inputDir.isDirectory()) {
- throw new RuntimeException("Could not find input directory: " + inputDir);
+ try {
+ TinyTree currentMappings = mappingsProvider.getMappings();
+ TinyTree targetMappings = getMappings(project, targetMappingsName, useLocalMappings);
+ migrateMappings(project, extension.getMinecraftMappedProvider(), inputDirPath, outputDirPath, currentMappings, targetMappings, extension);
+ project.getLogger().lifecycle(":remapped project written to " + outputDirPath.toAbsolutePath());
+ } catch (IOException e) {
+ throw new IllegalArgumentException("Could not find mappings for version " + officialMappingsVersion, e);
}
+ }
- if (!outputDir.exists()) {
- if (!outputDir.mkdirs()) {
- throw new RuntimeException("Could not create output directory:" + outputDir);
+ private TinyTree getMappings(Project project, String mappingsVersionOrPath, boolean useLocalMappings) throws IOException {
+ Path migrateMappingsDir = Files.createTempDirectory("migrate");
+ Path localMappingsOfVersion = migrateMappingsDir.resolve(mappingsVersionOrPath + ".tiny");
+
+ if (!Files.exists(localMappingsOfVersion)) {
+ if (useLocalMappings) {
+ Files.copy(Paths.get(mappingsVersionOrPath), localMappingsOfVersion);
+ } else {
+ String versionRelativePath = UrlEscapers.urlFragmentEscaper().escape(mappingsVersionOrPath);
+ String artifactUrl = "https://maven.fabricmc.net/net/fabricmc/yarn/" + versionRelativePath + "/yarn-" + versionRelativePath + ".jar";
+ File mappingsJar = File.createTempFile("migrateMappingsJar", ".jar");
+ project.getLogger().lifecycle(":downloading new mappings from " + artifactUrl);
+ FileUtils.copyURLToFile(new URL(artifactUrl), mappingsJar);
+
+ try (FileSystem jar = FileSystems.newFileSystem(mappingsJar.toPath(), null)) {
+ if (!Files.exists(migrateMappingsDir)) Files.createDirectory(migrateMappingsDir);
+ MappingsProvider.extractMappings(jar, localMappingsOfVersion);
+ }
}
}
- Mappings sourceMappings = extension.getMappingsProvider().getMappings();
- Mappings targetMappings;
-
- try (FileInputStream stream = new FileInputStream(mappingsFile)) {
- targetMappings = net.fabricmc.mappings.MappingsProvider.readTinyMappings(stream, false);
+ try (BufferedReader reader = Files.newBufferedReader(localMappingsOfVersion)) {
+ return TinyMappingFactory.loadWithDetection(reader);
}
+ }
+ private static void migrateMappings(Project project, MinecraftMappedProvider minecraftMappedProvider,
+ Path inputDir, Path outputDir, TinyTree currentMappings, TinyTree targetMappings, LoomGradleExtension extension
+ ) throws IOException {
project.getLogger().lifecycle(":joining mappings");
- MappingSet mappingSet = new MappingsJoiner(sourceMappings, targetMappings, "intermediary", "named").read();
+ MappingSet mappingSet = new MappingsJoiner(currentMappings, targetMappings,
+ "intermediary", "named").read();
project.getLogger().lifecycle(":remapping");
- Mercury mercury = new Mercury();
-
- for (File file : project.getConfigurations().getByName(Constants.MINECRAFT_DEPENDENCIES).getFiles()) {
- mercury.getClassPath().add(file.toPath());
- }
-
- for (File file : project.getConfigurations().getByName("compileClasspath").getFiles()) {
- mercury.getClassPath().add(file.toPath());
- }
+ Mercury mercury = SourceRemapper.createMercuryWithClassPath(project, false);
- mercury.getClassPath().add(extension.getMinecraftMappedProvider().MINECRAFT_MAPPED_JAR.toPath());
- mercury.getClassPath().add(extension.getMinecraftMappedProvider().MINECRAFT_INTERMEDIARY_JAR.toPath());
+ mercury.getClassPath().add(minecraftMappedProvider.MINECRAFT_MAPPED_JAR.toPath());
+ mercury.getClassPath().add(minecraftMappedProvider.MINECRAFT_INTERMEDIARY_JAR.toPath());
mercury.getProcessors().add(MercuryRemapper.create(mappingSet));
try {
- mercury.rewrite(inputDir.toPath(), outputDir.toPath());
+ mercury.rewrite(inputDir, outputDir);
} catch (Exception e) {
project.getLogger().warn("Could not remap fully!", e);
}
@@ -133,10 +167,19 @@ public class MigrateMappingsTask extends AbstractLoomTask {
}
public static class MappingsJoiner extends MappingsReader {
- private final Mappings sourceMappings, targetMappings;
+ private final TinyTree sourceMappings, targetMappings;
private final String fromNamespace, toNamespace;
- public MappingsJoiner(Mappings sourceMappings, Mappings targetMappings, String fromNamespace, String toNamespace) {
+ /**
+ * Say A is the source mappings and B is the target mappings.
+ * It does not map from intermediary to named but rather maps from named-A to named-B, by matching intermediary names.
+ * It goes through all of the intermediary names of A, and for every such intermediary name, call it I,
+ * matches the named mapping of I in A, with the named mapping of I in B.
+ * As you might imagine, this requires intermediary mappings to be stable across all versions.
+ * Since we only use intermediary names (and not descriptors) to match, and intermediary names are unique,
+ * this will migrate methods that have had their signature changed too.
+ */
+ public MappingsJoiner(TinyTree sourceMappings, TinyTree targetMappings, String fromNamespace, String toNamespace) {
this.sourceMappings = sourceMappings;
this.targetMappings = targetMappings;
this.fromNamespace = fromNamespace;
@@ -144,40 +187,51 @@ public class MigrateMappingsTask extends AbstractLoomTask {
}
@Override
- public MappingSet read(MappingSet mappings) throws IOException {
- Map<String, ClassEntry> targetClasses = new HashMap<>();
- Map<EntryTriple, FieldEntry> targetFields = new HashMap<>();
- Map<EntryTriple, MethodEntry> targetMethods = new HashMap<>();
+ public MappingSet read(MappingSet mappings) {
+ Map<String, ClassDef> targetClasses = new HashMap<>();
+ Map<String, FieldDef> targetFields = new HashMap<>();
+ Map<String, MethodDef> targetMethods = new HashMap<>();
- targetMappings.getClassEntries().forEach((c) -> targetClasses.put(c.get(fromNamespace), c));
- targetMappings.getFieldEntries().forEach((c) -> targetFields.put(c.get(fromNamespace), c));
- targetMappings.getMethodEntries().forEach((c) -> targetMethods.put(c.get(fromNamespace), c));
+ for (ClassDef newClass : targetMappings.getClasses()) {
+ targetClasses.put(newClass.getName(fromNamespace), newClass);
- for (ClassEntry entry : sourceMappings.getClassEntries()) {
- String from = entry.get(toNamespace);
- String to = targetClasses.getOrDefault(entry.get(fromNamespace), entry).get(toNamespace);
+ for (FieldDef field : newClass.getFields()) {
+ targetFields.put(field.getName(fromNamespace), field);
+ }
- mappings.getOrCreateClassMapping(from).setDeobfuscatedName(to);
+ for (MethodDef method : newClass.getMethods()) {
+ targetMethods.put(method.getName(fromNamespace), method);
+ }
}
- for (FieldEntry entry : sourceMappings.getFieldEntries()) {
- EntryTriple fromEntry = entry.get(toNamespace);
- EntryTriple toEntry = targetFields.getOrDefault(entry.get(fromNamespace), entry).get(toNamespace);
+ for (ClassDef oldClass : sourceMappings.getClasses()) {
+ String namedMappingOfSourceMapping = oldClass.getName(toNamespace);
+ String namedMappingOfTargetMapping = targetClasses.getOrDefault(oldClass.getName(fromNamespace), oldClass).getName(toNamespace);
- mappings.getOrCreateClassMapping(fromEntry.getOwner()).getOrCreateFieldMapping(fromEntry.getName(), fromEntry.getDesc()).setDeobfuscatedName(toEntry.getName());
- }
-
- for (MethodEntry entry : sourceMappings.getMethodEntries()) {
- EntryTriple fromEntry = entry.get(toNamespace);
- EntryTriple toEntry = targetMethods.getOrDefault(entry.get(fromNamespace), entry).get(toNamespace);
+ ClassMapping classMapping = mappings.getOrCreateClassMapping(namedMappingOfSourceMapping).setDeobfuscatedName(namedMappingOfTargetMapping);
- mappings.getOrCreateClassMapping(fromEntry.getOwner()).getOrCreateMethodMapping(fromEntry.getName(), fromEntry.getDesc()).setDeobfuscatedName(toEntry.getName());
+ mapMembers(oldClass.getFields(), targetFields, classMapping::getOrCreateFieldMapping);
+ mapMembers(oldClass.getMethods(), targetMethods, classMapping::getOrCreateMethodMapping);
}
return mappings;
}
+ private <T extends Descriptored> void mapMembers(Collection<T> oldMembers, Map<String, T> newMembers,
+ BiFunction<String, String, Mapping> mapper) {
+ for (T oldMember : oldMembers) {
+ String oldName = oldMember.getName(toNamespace);
+ String oldDescriptor = oldMember.getDescriptor(toNamespace);
+ // We only use the intermediary name (and not the descriptor) because every method has a unique intermediary name
+ String newName = newMembers.getOrDefault(oldMember.getName(fromNamespace), oldMember).getName(toNamespace);
+
+ mapper.apply(oldName, oldDescriptor).setDeobfuscatedName(newName);
+ }
+ }
+
@Override
- public void close() throws IOException { }
+ public void close() {
+ }
}
}
+
diff --git a/src/main/java/net/fabricmc/loom/task/RemapJarTask.java b/src/main/java/net/fabricmc/loom/task/RemapJarTask.java
index 3936fc6d..446702f5 100644
--- a/src/main/java/net/fabricmc/loom/task/RemapJarTask.java
+++ b/src/main/java/net/fabricmc/loom/task/RemapJarTask.java
@@ -76,16 +76,16 @@ public class RemapJarTask extends Jar {
String toM = "intermediary";
Set<File> classpathFiles = new LinkedHashSet<>(
- project.getConfigurations().getByName("compileClasspath").getFiles()
+ project.getConfigurations().getByName("compileClasspath").getFiles()
);
Path[] classpath = classpathFiles.stream().map(File::toPath).filter((p) -> !input.equals(p) && Files.exists(p)).toArray(Path[]::new);
- File mixinMapFile = mappingsProvider.MAPPINGS_MIXIN_EXPORT;
+ File mixinMapFile = mappingsProvider.mappingsMixinExport;
Path mixinMapPath = mixinMapFile.toPath();
TinyRemapper.Builder remapperBuilder = TinyRemapper.newRemapper();
- remapperBuilder = remapperBuilder.withMappings(TinyRemapperMappingsHelper.create(mappingsProvider.getMappings(), fromM, toM));
+ remapperBuilder = remapperBuilder.withMappings(TinyRemapperMappingsHelper.create(mappingsProvider.getMappings(), fromM, toM, false));
if (mixinMapFile.exists()) {
remapperBuilder = remapperBuilder.withMappings(TinyUtils.createTinyMappingProvider(mixinMapPath, fromM, toM));
diff --git a/src/main/java/net/fabricmc/loom/util/Constants.java b/src/main/java/net/fabricmc/loom/util/Constants.java
index c2f0eab2..26aa4ff3 100644
--- a/src/main/java/net/fabricmc/loom/util/Constants.java
+++ b/src/main/java/net/fabricmc/loom/util/Constants.java
@@ -50,4 +50,5 @@ public class Constants {
public static final String MINECRAFT_NAMED = "minecraftNamed";
public static final String MINECRAFT_LINEMAPPED = "minecraftLinemapped";
public static final String MAPPINGS = "mappings";
+ public static final String MAPPINGS_FINAL = "mappingsFinal";
}
diff --git a/src/main/java/net/fabricmc/loom/util/MapJarsTiny.java b/src/main/java/net/fabricmc/loom/util/MapJarsTiny.java
index 2f23e6f8..3e671923 100644
--- a/src/main/java/net/fabricmc/loom/util/MapJarsTiny.java
+++ b/src/main/java/net/fabricmc/loom/util/MapJarsTiny.java
@@ -56,7 +56,11 @@ public class MapJarsTiny {
project.getLogger().lifecycle(":remapping minecraft (TinyRemapper, " + fromM + " -> " + toM + ")");
- TinyRemapper remapper = TinyRemapper.newRemapper().withMappings(TinyRemapperMappingsHelper.create(mappingsProvider.getMappings(), fromM, toM)).renameInvalidLocals(true).rebuildSourceFilenames(true).build();
+ 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);
@@ -64,7 +68,7 @@ public class MapJarsTiny {
remapper.readInputs(input);
remapper.apply(outputConsumer);
} catch (Exception e) {
- throw new RuntimeException("Failed to remap JAR", e);
+ throw new RuntimeException("Failed to remap JAR " + input + " with mappings from " + mappingsProvider.tinyMappings, e);
} finally {
remapper.finish();
}
diff --git a/src/main/java/net/fabricmc/loom/util/ModProcessor.java b/src/main/java/net/fabricmc/loom/util/ModProcessor.java
index cccd2b43..09c746f5 100644
--- a/src/main/java/net/fabricmc/loom/util/ModProcessor.java
+++ b/src/main/java/net/fabricmc/loom/util/ModProcessor.java
@@ -41,13 +41,12 @@ import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import org.apache.commons.io.IOUtils;
+import org.gradle.api.Project;
+import org.gradle.api.artifacts.Configuration;
import org.zeroturnaround.zip.ZipUtil;
import org.zeroturnaround.zip.commons.FileUtils;
import org.zeroturnaround.zip.transform.StringZipEntryTransformer;
import org.zeroturnaround.zip.transform.ZipEntryTransformerEntry;
-import org.gradle.api.Project;
-import org.gradle.api.artifacts.Configuration;
-import org.gradle.internal.impldep.aQute.lib.strings.Strings;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.providers.MappingsProvider;
@@ -110,7 +109,7 @@ public class ModProcessor {
JarEntry entry = parentJar.getJarEntry(fileName);
if (entry == null) {
- throw new RuntimeException(Strings.format("%s was not found in %s", fileName, parentJar.getName()));
+ throw new RuntimeException(String.format("%s was not found in %s", fileName, parentJar.getName()));
}
File nestedFile = new File(extension.getNestedModCache(), fileName.substring(fileName.lastIndexOf("/")));
@@ -133,7 +132,7 @@ public class ModProcessor {
private static void stripNestedJars(File file) {
//Strip out all contained jar info as we dont want loader to try and load the jars contained in dev.
- ZipUtil.transformEntries(file, new ZipEntryTransformerEntry[]{(new ZipEntryTransformerEntry("fabric.mod.json", new StringZipEntryTransformer() {
+ ZipUtil.transformEntries(file, new ZipEntryTransformerEntry[] {(new ZipEntryTransformerEntry("fabric.mod.json", new StringZipEntryTransformer() {
@Override
protected String transform(ZipEntry zipEntry, String input) throws IOException {
JsonObject json = GSON.fromJson(input, JsonObject.class);
@@ -151,8 +150,6 @@ public class ModProcessor {
MinecraftMappedProvider mappedProvider = extension.getMinecraftMappedProvider();
MappingsProvider mappingsProvider = extension.getMappingsProvider();
- File mappingsFile = mappingsProvider.MAPPINGS_TINY;
- Path mappings = mappingsFile.toPath();
Path inputPath = input.getAbsoluteFile().toPath();
Path mc = mappedProvider.MINECRAFT_INTERMEDIARY_JAR.toPath();
Path[] mcDeps = mappedProvider.getMapperPaths().stream().map(File::toPath).toArray(Path[]::new);
@@ -170,7 +167,9 @@ public class ModProcessor {
project.getLogger().lifecycle(":remapping " + input.getName() + " (TinyRemapper, " + fromM + " -> " + toM + ")");
- TinyRemapper remapper = TinyRemapper.newRemapper().withMappings(TinyRemapperMappingsHelper.create(mappingsProvider.getMappings(), fromM, toM)).build();
+ TinyRemapper remapper = TinyRemapper.newRemapper()
+ .withMappings(TinyRemapperMappingsHelper.create(mappingsProvider.getMappings(), fromM, toM, false))
+ .build();
try (OutputConsumerPath outputConsumer = new OutputConsumerPath.Builder(Paths.get(output.getAbsolutePath())).build()) {
outputConsumer.addNonClassFiles(inputPath);
diff --git a/src/main/java/net/fabricmc/loom/util/SourceRemapper.java b/src/main/java/net/fabricmc/loom/util/SourceRemapper.java
index 258dc848..e2eff620 100644
--- a/src/main/java/net/fabricmc/loom/util/SourceRemapper.java
+++ b/src/main/java/net/fabricmc/loom/util/SourceRemapper.java
@@ -31,18 +31,18 @@ import java.nio.file.Path;
import org.cadixdev.lorenz.MappingSet;
import org.cadixdev.lorenz.io.MappingsReader;
+import org.cadixdev.lorenz.model.ClassMapping;
import org.cadixdev.mercury.Mercury;
import org.cadixdev.mercury.remapper.MercuryRemapper;
-import org.zeroturnaround.zip.ZipUtil;
import org.gradle.api.Project;
+import org.zeroturnaround.zip.ZipUtil;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.providers.MappingsProvider;
-import net.fabricmc.mappings.ClassEntry;
-import net.fabricmc.mappings.EntryTriple;
-import net.fabricmc.mappings.FieldEntry;
-import net.fabricmc.mappings.Mappings;
-import net.fabricmc.mappings.MethodEntry;
+import net.fabricmc.mapping.tree.ClassDef;
+import net.fabricmc.mapping.tree.FieldDef;
+import net.fabricmc.mapping.tree.MethodDef;
+import net.fabricmc.mapping.tree.TinyTree;
import net.fabricmc.stitch.util.StitchUtil;
public class SourceRemapper {
@@ -58,7 +58,7 @@ public class SourceRemapper {
MappingSet mappings = extension.getOrCreateSrcMappingCache(toNamed ? 1 : 0, () -> {
try {
- Mappings m = mappingsProvider.getMappings();
+ 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) {
@@ -69,17 +69,7 @@ public class SourceRemapper {
project.getLogger().info(":remapping source jar");
Mercury mercury = extension.getOrCreateSrcMercuryCache(toNamed ? 1 : 0, () -> {
- Mercury m = new Mercury();
-
- for (File file : project.getConfigurations().getByName(Constants.MINECRAFT_DEPENDENCIES).getFiles()) {
- m.getClassPath().add(file.toPath());
- }
-
- if (!toNamed) {
- for (File file : project.getConfigurations().getByName("compileClasspath").getFiles()) {
- m.getClassPath().add(file.toPath());
- }
- }
+ Mercury m = createMercuryWithClassPath(project, toNamed);
for (Path file : extension.getUnmappedMods()) {
if (Files.isRegularFile(file)) {
@@ -159,6 +149,22 @@ public class SourceRemapper {
});
}
+ public static Mercury createMercuryWithClassPath(Project project, boolean toNamed) {
+ Mercury m = new Mercury();
+
+ for (File file : project.getConfigurations().getByName(Constants.MINECRAFT_DEPENDENCIES).getFiles()) {
+ m.getClassPath().add(file.toPath());
+ }
+
+ if (!toNamed) {
+ for (File file : project.getConfigurations().getByName("compileClasspath").getFiles()) {
+ m.getClassPath().add(file.toPath());
+ }
+ }
+
+ return m;
+ }
+
private static boolean isJavaFile(Path path) {
String name = path.getFileName().toString();
// ".java" is not a valid java file
@@ -166,39 +172,36 @@ public class SourceRemapper {
}
public static class TinyReader extends MappingsReader {
- private final Mappings m;
+ private final TinyTree mappings;
private final String from, to;
- public TinyReader(Mappings m, String from, String to) {
- this.m = m;
+ public TinyReader(TinyTree m, String from, String to) {
+ this.mappings = m;
this.from = from;
this.to = to;
}
@Override
public MappingSet read(final MappingSet mappings) {
- for (ClassEntry entry : m.getClassEntries()) {
- mappings.getOrCreateClassMapping(entry.get(from)).setDeobfuscatedName(entry.get(to));
- }
+ for (ClassDef classDef : this.mappings.getClasses()) {
+ ClassMapping classMapping = mappings.getOrCreateClassMapping(classDef.getName(from))
+ .setDeobfuscatedName(classDef.getName(to));
- for (FieldEntry entry : m.getFieldEntries()) {
- EntryTriple fromEntry = entry.get(from);
- EntryTriple toEntry = entry.get(to);
-
- mappings.getOrCreateClassMapping(fromEntry.getOwner()).getOrCreateFieldMapping(fromEntry.getName(), fromEntry.getDesc()).setDeobfuscatedName(toEntry.getName());
- }
-
- for (MethodEntry entry : m.getMethodEntries()) {
- EntryTriple fromEntry = entry.get(from);
- EntryTriple toEntry = entry.get(to);
+ for (FieldDef field : classDef.getFields()) {
+ classMapping.getOrCreateFieldMapping(field.getName(from), field.getDescriptor(from))
+ .setDeobfuscatedName(field.getName(to));
+ }
- mappings.getOrCreateClassMapping(fromEntry.getOwner()).getOrCreateMethodMapping(fromEntry.getName(), fromEntry.getDesc()).setDeobfuscatedName(toEntry.getName());
+ for (MethodDef method : classDef.getMethods()) {
+ classMapping.getOrCreateMethodMapping(method.getName(from), method.getDescriptor(from))
+ .setDeobfuscatedName(method.getName(to));
+ }
}
return mappings;
}
@Override
- public void close() throws IOException { }
+ public void close() { }
}
}
diff --git a/src/main/java/net/fabricmc/loom/util/TinyRemapperMappingsHelper.java b/src/main/java/net/fabricmc/loom/util/TinyRemapperMappingsHelper.java
index 0652e520..b9964020 100644
--- a/src/main/java/net/fabricmc/loom/util/TinyRemapperMappingsHelper.java
+++ b/src/main/java/net/fabricmc/loom/util/TinyRemapperMappingsHelper.java
@@ -24,31 +24,47 @@
package net.fabricmc.loom.util;
-import net.fabricmc.mappings.ClassEntry;
-import net.fabricmc.mappings.EntryTriple;
-import net.fabricmc.mappings.FieldEntry;
-import net.fabricmc.mappings.Mappings;
-import net.fabricmc.mappings.MethodEntry;
+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.tinyremapper.IMappingProvider;
-import net.fabricmc.tinyremapper.MemberInstance;
public class TinyRemapperMappingsHelper {
private TinyRemapperMappingsHelper() { }
- public static IMappingProvider create(Mappings mappings, String from, String to) {
- return (classMap, fieldMap, methodMap) -> {
- for (ClassEntry entry : mappings.getClassEntries()) {
- classMap.put(entry.get(from), entry.get(to));
- }
+ private static IMappingProvider.Member memberOf(String className, String memberName, String descriptor) {
+ return new IMappingProvider.Member(className, memberName, descriptor);
+ }
- for (FieldEntry entry : mappings.getFieldEntries()) {
- EntryTriple fromTriple = entry.get(from);
- fieldMap.put(fromTriple.getOwner() + "/" + MemberInstance.getFieldId(fromTriple.getName(), fromTriple.getDesc()), entry.get(to).getName());
- }
+ public static IMappingProvider create(TinyTree mappings, String from, String to, boolean remapLocalVariables) {
+ return (acceptor) -> {
+ for (ClassDef 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 (MethodDef method : classDef.getMethods()) {
+ IMappingProvider.Member methodIdentifier = memberOf(className, method.getName(from), method.getDescriptor(from));
+ acceptor.acceptMethod(methodIdentifier, method.getName(to));
+
+ if (remapLocalVariables) {
+ for (ParameterDef parameter : method.getParameters()) {
+ acceptor.acceptMethodArg(methodIdentifier, parameter.getLocalVariableIndex(), parameter.getName(to));
+ }
- for (MethodEntry entry : mappings.getMethodEntries()) {
- EntryTriple fromTriple = entry.get(from);
- methodMap.put(fromTriple.getOwner() + "/" + MemberInstance.getMethodId(fromTriple.getName(), fromTriple.getDesc()), entry.get(to).getName());
+ for (LocalVariableDef localVariable : method.getLocalVariables()) {
+ acceptor.acceptMethodVar(methodIdentifier, localVariable.getLocalVariableIndex(),
+ localVariable.getLocalVariableStartOffset(), localVariable.getLocalVariableTableIndex(),
+ localVariable.getName(to));
+ }
+ }
+ }
}
};
}
diff --git a/src/test/groovy/net/fabricmc/loom/BuildUtils.groovy b/src/test/groovy/net/fabricmc/loom/BuildUtils.groovy
index 8391fec4..bb2ca787 100644
--- a/src/test/groovy/net/fabricmc/loom/BuildUtils.groovy
+++ b/src/test/groovy/net/fabricmc/loom/BuildUtils.groovy
@@ -16,6 +16,7 @@ archivesBaseName = project.archives_base_name
version = project.mod_version
group = project.maven_group
+
minecraft {
}
diff --git a/src/test/groovy/net/fabricmc/loom/EmptyBuildFunctionalTest.groovy b/src/test/groovy/net/fabricmc/loom/EmptyBuildFunctionalTest.groovy
index b9d63012..e42ee12c 100644
--- a/src/test/groovy/net/fabricmc/loom/EmptyBuildFunctionalTest.groovy
+++ b/src/test/groovy/net/fabricmc/loom/EmptyBuildFunctionalTest.groovy
@@ -35,7 +35,7 @@ class EmptyBuildFunctionalTest extends Specification {
when:
def result = GradleRunner.create()
.withProjectDir(testProjectDir.root)
- .withArguments('build')
+ .withArguments('build',"--stacktrace")
.withPluginClasspath()
.withGradleVersion("4.9")
.build()
diff --git a/src/test/groovy/net/fabricmc/loom/SimpleBuildFunctionalTest.groovy b/src/test/groovy/net/fabricmc/loom/SimpleBuildFunctionalTest.groovy
index 3db6cb58..9706e7ea 100644
--- a/src/test/groovy/net/fabricmc/loom/SimpleBuildFunctionalTest.groovy
+++ b/src/test/groovy/net/fabricmc/loom/SimpleBuildFunctionalTest.groovy
@@ -45,9 +45,10 @@ class SimpleBuildFunctionalTest extends Specification {
when:
def result = GradleRunner.create()
.withProjectDir(testProjectDir.root)
- .withArguments('build')
+ .withArguments('build',"--stacktrace")
.withPluginClasspath()
.withGradleVersion("4.9")
+ .withDebug(true)
.build()
then:
@@ -55,6 +56,7 @@ class SimpleBuildFunctionalTest extends Specification {
where:
mcVersion | yarnVersion | loaderVersion | fabricVersion
+ '19w45a' | '19w45a+build.2:v2' | '0.6.2+build.166' | '0.4.9+build.258-1.15'
'1.14' | '1.14+build.21' | '0.4.8+build.155' | '0.3.0+build.184'
'1.14.1' | '1.14.1+build.10' | '0.4.8+build.155' | '0.3.0+build.184'
'1.14.2' | '1.14.2+build.7' | '0.4.8+build.155' | '0.3.0+build.184'