Allow remapping to other namespaces

This commit is contained in:
shedaniel
2021-04-13 10:07:26 +08:00
parent f45f47b1b0
commit 635fd8a55d
5 changed files with 95 additions and 56 deletions

View File

@@ -136,11 +136,12 @@ public class LoomGradleExtension {
}
public MappingSet getOrCreateSrcMappingCache(int id, Supplier<MappingSet> factory) {
if (id < 0 || id >= srcMappingCache.length) return factory.get();
return srcMappingCache[id] != null ? srcMappingCache[id] : (srcMappingCache[id] = factory.get());
}
public Mercury getOrCreateSrcMercuryCache(int id, Supplier<Mercury> factory) {
if (id == -1) return factory.get();
if (id < 0 || id >= srcMercuryCache.length) return factory.get();
return srcMercuryCache[id] != null ? srcMercuryCache[id] : (srcMercuryCache[id] = factory.get());
}

View File

@@ -268,7 +268,6 @@ public final class CompileConfiguration {
}
if (extension.isForge()) {
remapJarTask.getToM().set("srg");
((Jar) jarTask).manifest(manifest -> {
List<String> configs = new ArrayList<>();
@@ -342,10 +341,11 @@ public final class CompileConfiguration {
AbstractArchiveTask sourcesTask = (AbstractArchiveTask) project1.getTasks().getByName("sourcesJar");
RemapSourcesJarTask remapSourcesJarTask = (RemapSourcesJarTask) project1.getTasks().findByName("remapSourcesJar");
remapSourcesJarTask.setInput(sourcesTask.getArchivePath());
remapSourcesJarTask.setOutput(sourcesTask.getArchivePath());
sourcesTask.setClassifier(sourcesTask.getClassifier() == null ? "dev" : sourcesTask.getClassifier() + "-dev");
remapSourcesJarTask.setInput(sourcesTask.getArchivePath());
remapSourcesJarTask.doLast(task -> project1.getArtifacts().add("archives", remapSourcesJarTask.getOutput()));
remapSourcesJarTask.dependsOn(project1.getTasks().getByName("sourcesJar"));
remapSourcesJarTask.dependsOn(sourcesTask);
if (extension.isShareCaches()) {
remapSourcesJarTask.setSourceRemapper(remapper);

View File

@@ -70,6 +70,7 @@ import net.fabricmc.loom.build.NestedJars;
import net.fabricmc.loom.configuration.accesswidener.AccessWidenerJarProcessor;
import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider;
import net.fabricmc.loom.util.LoggerFilter;
import net.fabricmc.loom.util.SourceRemapper;
import net.fabricmc.loom.util.TinyRemapperMappingsHelper;
import net.fabricmc.loom.util.ZipReprocessorUtil;
import net.fabricmc.loom.util.gradle.GradleSupport;
@@ -101,7 +102,7 @@ public class RemapJarTask extends Jar {
fromM = getProject().getObjects().property(String.class);
toM = getProject().getObjects().property(String.class);
fromM.set("named");
toM.set("intermediary");
toM.set(SourceRemapper.intermediary(getProject()));
// false by default, I have no idea why I have to do it for this property and not the other one
remapAccessWidener.set(false);
}
@@ -135,12 +136,12 @@ public class RemapJarTask extends Jar {
LoggerFilter.replaceSystemOut();
TinyRemapper.Builder remapperBuilder = TinyRemapper.newRemapper();
remapperBuilder.logger(getProject().getLogger()::lifecycle);
remapperBuilder = remapperBuilder.withMappings(TinyRemapperMappingsHelper.create(extension.isForge() ? mappingsProvider.getMappingsWithSrg() : mappingsProvider.getMappings(), fromM, toM, false));
remapperBuilder = remapperBuilder.withMappings(TinyRemapperMappingsHelper.create(extension.shouldGenerateSrgTiny() ? mappingsProvider.getMappingsWithSrg() : mappingsProvider.getMappings(), fromM, toM, false));
for (File mixinMapFile : extension.getAllMixinMappings()) {
if (mixinMapFile.exists()) {
IMappingProvider provider = TinyUtils.createTinyMappingProvider(mixinMapFile.toPath(), fromM, "intermediary");
remapperBuilder = remapperBuilder.withMappings(extension.isForge() ? remapToSrg(extension, provider) : provider);
remapperBuilder = remapperBuilder.withMappings(!toM.equals("intermediary") ? remapToSrg(extension, provider, fromM, toM) : provider);
}
}
@@ -149,7 +150,7 @@ public class RemapJarTask extends Jar {
remapOption.execute(remapperBuilder);
}
project.getLogger().info(":remapping " + input.getFileName());
project.getLogger().info(":remapping " + input.getFileName() + " from " + fromM + " to " + toM);
StringBuilder rc = new StringBuilder("Remap classpath: ");
@@ -194,7 +195,7 @@ public class RemapJarTask extends Jar {
Gson gson = new GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create();
JsonObject refmapElement = gson.fromJson(refmapReader, JsonObject.class);
refmapElement = RefmapRemapper.remap(new Remapper() {
ReferenceRemapper remapper = createReferenceRemapper(extension);
ReferenceRemapper remapper = createReferenceRemapper(extension, fromM, toM);
@Override
@Nullable
@@ -230,17 +231,17 @@ public class RemapJarTask extends Jar {
}
}
private ReferenceRemapper createReferenceRemapper(LoomGradleExtension extension) throws IOException {
TinyTree srg = extension.getMappingsProvider().getMappingsWithSrg();
private ReferenceRemapper createReferenceRemapper(LoomGradleExtension extension, String fromM, String toM) throws IOException {
TinyTree mappings = extension.shouldGenerateSrgTiny() ? extension.getMappingsProvider().getMappingsWithSrg() : extension.getMappingsProvider().getMappings();
return new SimpleReferenceRemapper(new SimpleReferenceRemapper.Remapper() {
@Override
@Nullable
public String mapClass(String value) {
return srg.getClasses().stream()
.filter(classDef -> Objects.equals(classDef.getName("intermediary"), value))
return mappings.getClasses().stream()
.filter(classDef -> Objects.equals(classDef.getName(fromM), value))
.findFirst()
.map(classDef -> classDef.getName("srg"))
.map(classDef -> classDef.getName(toM))
.orElse(null);
}
@@ -248,24 +249,24 @@ public class RemapJarTask extends Jar {
@Nullable
public String mapMethod(@Nullable String className, String methodName, String methodDescriptor) {
if (className != null) {
Optional<ClassDef> classDef = srg.getClasses().stream()
.filter(c -> Objects.equals(c.getName("intermediary"), className))
Optional<ClassDef> classDef = mappings.getClasses().stream()
.filter(c -> Objects.equals(c.getName(fromM), className))
.findFirst();
if (classDef.isPresent()) {
for (MethodDef methodDef : classDef.get().getMethods()) {
if (Objects.equals(methodDef.getName("intermediary"), methodName) && Objects.equals(methodDef.getDescriptor("intermediary"), methodDescriptor)) {
return methodDef.getName("srg");
if (Objects.equals(methodDef.getName(fromM), methodName) && Objects.equals(methodDef.getDescriptor(fromM), methodDescriptor)) {
return methodDef.getName(toM);
}
}
}
}
return srg.getClasses().stream()
return mappings.getClasses().stream()
.flatMap(classDef -> classDef.getMethods().stream())
.filter(methodDef -> Objects.equals(methodDef.getName("intermediary"), methodName) && Objects.equals(methodDef.getDescriptor("intermediary"), methodDescriptor))
.filter(methodDef -> Objects.equals(methodDef.getName(fromM), methodName) && Objects.equals(methodDef.getDescriptor(fromM), methodDescriptor))
.findFirst()
.map(methodDef -> methodDef.getName("srg"))
.map(methodDef -> methodDef.getName(toM))
.orElse(null);
}
@@ -273,24 +274,24 @@ public class RemapJarTask extends Jar {
@Nullable
public String mapField(@Nullable String className, String fieldName, String fieldDescriptor) {
if (className != null) {
Optional<ClassDef> classDef = srg.getClasses().stream()
.filter(c -> Objects.equals(c.getName("intermediary"), className))
Optional<ClassDef> classDef = mappings.getClasses().stream()
.filter(c -> Objects.equals(c.getName(fromM), className))
.findFirst();
if (classDef.isPresent()) {
for (FieldDef fieldDef : classDef.get().getFields()) {
if (Objects.equals(fieldDef.getName("intermediary"), fieldName) && Objects.equals(fieldDef.getDescriptor("intermediary"), fieldDescriptor)) {
return fieldDef.getName("srg");
if (Objects.equals(fieldDef.getName(fromM), fieldName) && Objects.equals(fieldDef.getDescriptor(fromM), fieldDescriptor)) {
return fieldDef.getName(toM);
}
}
}
}
return srg.getClasses().stream()
return mappings.getClasses().stream()
.flatMap(classDef -> classDef.getFields().stream())
.filter(fieldDef -> Objects.equals(fieldDef.getName("intermediary"), fieldName) && Objects.equals(fieldDef.getDescriptor("intermediary"), fieldDescriptor))
.filter(fieldDef -> Objects.equals(fieldDef.getName(fromM), fieldName) && Objects.equals(fieldDef.getDescriptor(fromM), fieldDescriptor))
.findFirst()
.map(fieldDef -> fieldDef.getName("srg"))
.map(fieldDef -> fieldDef.getName(toM))
.orElse(null);
}
});
@@ -314,19 +315,21 @@ public class RemapJarTask extends Jar {
if (extension.isRootProject()) {
jarRemapper.addToClasspath(getRemapClasspath());
jarRemapper.addMappings(TinyRemapperMappingsHelper.create(extension.isForge() ? mappingsProvider.getMappingsWithSrg() : mappingsProvider.getMappings(), fromM, toM, false));
jarRemapper.addMappings(TinyRemapperMappingsHelper.create(extension.shouldGenerateSrgTiny() ? mappingsProvider.getMappingsWithSrg() : mappingsProvider.getMappings(), fromM, toM, false));
}
for (File mixinMapFile : extension.getAllMixinMappings()) {
if (mixinMapFile.exists()) {
IMappingProvider provider = TinyUtils.createTinyMappingProvider(mixinMapFile.toPath(), fromM, "intermediary");
jarRemapper.addMappings(extension.isForge() ? remapToSrg(extension, provider) : provider);
jarRemapper.addMappings(!toM.equals("intermediary") ? remapToSrg(extension, provider, fromM, toM) : provider);
}
}
// Add remap options to the jar remapper
jarRemapper.addOptions(this.remapOptions);
project.getLogger().info(":scheduling remap " + input.getFileName() + " from " + fromM + " to " + toM);
jarRemapper.scheduleRemap(input, output)
.supplyAccessWidener((remapData, remapper) -> {
if (getRemapAccessWidener().getOrElse(false) && extension.accessWidener != null) {
@@ -369,42 +372,42 @@ public class RemapJarTask extends Jar {
});
}
private IMappingProvider remapToSrg(LoomGradleExtension extension, IMappingProvider parent) throws IOException {
TinyTree srg = extension.getMappingsProvider().getMappingsWithSrg();
private IMappingProvider remapToSrg(LoomGradleExtension extension, IMappingProvider parent, String fromM, String toM) throws IOException {
TinyTree mappings = extension.shouldGenerateSrgTiny() ? extension.getMappingsProvider().getMappingsWithSrg() : extension.getMappingsProvider().getMappings();
return sink -> {
parent.load(new IMappingProvider.MappingAcceptor() {
@Override
public void acceptClass(String srcName, String dstName) {
String srgName = srg.getClasses()
String srgName = mappings.getClasses()
.stream()
.filter(it -> Objects.equals(it.getName("intermediary"), dstName))
.filter(it -> Objects.equals(it.getName(fromM), dstName))
.findFirst()
.map(it -> it.getName("srg"))
.map(it -> it.getName(toM))
.orElse(dstName);
sink.acceptClass(srcName, srgName);
}
@Override
public void acceptMethod(IMappingProvider.Member method, String dstName) {
String srgName = srg.getClasses()
String srgName = mappings.getClasses()
.stream()
.flatMap(it -> it.getMethods().stream())
.filter(it -> Objects.equals(it.getName("intermediary"), dstName))
.filter(it -> Objects.equals(it.getName(fromM), dstName))
.findFirst()
.map(it -> it.getName("srg"))
.map(it -> it.getName(toM))
.orElse(dstName);
sink.acceptMethod(method, srgName);
}
@Override
public void acceptField(IMappingProvider.Member field, String dstName) {
String srgName = srg.getClasses()
String srgName = mappings.getClasses()
.stream()
.flatMap(it -> it.getFields().stream())
.filter(it -> Objects.equals(it.getName("intermediary"), dstName))
.filter(it -> Objects.equals(it.getName(fromM), dstName))
.findFirst()
.map(it -> it.getName("srg"))
.map(it -> it.getName(toM))
.orElse(dstName);
sink.acceptField(field, srgName);
}

View File

@@ -40,6 +40,7 @@ import net.fabricmc.loom.util.ZipReprocessorUtil;
public class RemapSourcesJarTask extends AbstractLoomTask {
private Object input;
private Object output;
private String from = "named";
private String direction = "intermediary";
private SourceRemapper sourceRemapper = null;
private final Property<Boolean> archivePreserveFileTimestamps;
@@ -54,7 +55,13 @@ public class RemapSourcesJarTask extends AbstractLoomTask {
@TaskAction
public void remap() throws Exception {
if (sourceRemapper == null) {
SourceRemapper.remapSources(getProject(), getInput(), getOutput(), direction.equals("named"));
if (from.equals(direction)) {
SourceRemapper.remapSources(getProject(), getInput(), getOutput(),
direction.equals("named") ? SourceRemapper.intermediary(getProject()) : "named", direction);
} else {
SourceRemapper.remapSources(getProject(), getInput(), getOutput(), from, direction);
}
ZipReprocessorUtil.reprocessZip(getOutput(), archivePreserveFileTimestamps.getOrElse(true), archiveReproducibleFileOrder.getOrElse(false));
} else {
sourceRemapper.scheduleRemapSources(getInput(), getOutput(), archivePreserveFileTimestamps.getOrElse(true), archiveReproducibleFileOrder.getOrElse(false));
@@ -81,6 +88,11 @@ public class RemapSourcesJarTask extends AbstractLoomTask {
return getProject().file(output == null ? input : output);
}
@Input
public String getSourceNamespace() {
return from;
}
@Input
public String getTargetNamespace() {
return direction;
@@ -94,6 +106,10 @@ public class RemapSourcesJarTask extends AbstractLoomTask {
this.output = output;
}
public void setSourceNamespace(String value) {
this.from = value;
}
public void setTargetNamespace(String value) {
this.direction = value;
}

View File

@@ -52,18 +52,29 @@ import net.fabricmc.stitch.util.StitchUtil;
public class SourceRemapper {
private final Project project;
private final boolean toNamed;
private String from;
private String to;
private final List<Consumer<ProgressLogger>> remapTasks = new ArrayList<>();
private Mercury mercury;
public SourceRemapper(Project project, boolean toNamed) {
this.project = project;
this.toNamed = toNamed;
public SourceRemapper(Project project, boolean named) {
this(project, named ? intermediary(project) : "named", !named ? intermediary(project) : "named");
}
public static void remapSources(Project project, File input, File output, boolean named) throws Exception {
SourceRemapper sourceRemapper = new SourceRemapper(project, named);
public static String intermediary(Project project) {
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
return extension.isForge() ? "srg" : "intermediary";
}
public SourceRemapper(Project project, String from, String to) {
this.project = project;
this.from = from;
this.to = to;
}
public static void remapSources(Project project, File input, File output, String from, String to) throws Exception {
SourceRemapper sourceRemapper = new SourceRemapper(project, from, to);
sourceRemapper.scheduleRemapSources(input, output, false, true);
sourceRemapper.remapAll();
}
@@ -109,7 +120,7 @@ public class SourceRemapper {
}
private void remapSourcesInner(File source, File destination) throws Exception {
project.getLogger().info(":remapping source jar");
project.getLogger().info(":remapping source jar " + source.getName() + " from " + from + " to " + to);
Mercury mercury = getMercuryInstance();
if (source.equals(destination)) {
@@ -170,19 +181,27 @@ public class SourceRemapper {
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
MappingsProvider mappingsProvider = extension.getMappingsProvider();
MappingSet mappings = extension.getOrCreateSrcMappingCache(toNamed ? 1 : 0, () -> {
String intermediary = extension.isForge() ? "srg" : "intermediary";
int id = -1;
if (from.equals(intermediary) && to.equals("named")) {
id = 1;
} else if (to.equals(intermediary) && from.equals("named")) {
id = 0;
}
MappingSet mappings = extension.getOrCreateSrcMappingCache(id, () -> {
try {
String intermediary = extension.isForge() ? "srg" : "intermediary";
TinyTree m = extension.isForge() ? mappingsProvider.getMappingsWithSrg() : mappingsProvider.getMappings();
project.getLogger().info(":loading " + (toNamed ? intermediary + " -> named" : "named -> " + intermediary) + " source mappings");
return new TinyMappingsReader(m, toNamed ? intermediary : "named", toNamed ? "named" : intermediary).read();
TinyTree m = extension.shouldGenerateSrgTiny() ? mappingsProvider.getMappingsWithSrg() : mappingsProvider.getMappings();
project.getLogger().info(":loading " + from + " -> " + to + " source mappings");
return new TinyMappingsReader(m, from, to).read();
} catch (Exception e) {
throw new RuntimeException(e);
}
});
Mercury mercury = extension.getOrCreateSrcMercuryCache(toNamed ? 1 : 0, () -> {
Mercury m = createMercuryWithClassPath(project, toNamed);
Mercury mercury = extension.getOrCreateSrcMercuryCache(id, () -> {
Mercury m = createMercuryWithClassPath(project, to.equals("named"));
for (File file : extension.getUnmappedModCollection()) {
Path path = file.toPath();