Merge remote-tracking branch 'FabricMC/dev/0.10' into dev/0.10.0

# Conflicts:
#	src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java
#	src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftMappedProvider.java
#	src/main/java/net/fabricmc/loom/util/TinyRemapperHelper.java
This commit is contained in:
shedaniel
2021-09-19 20:20:37 +08:00
5 changed files with 133 additions and 47 deletions

View File

@@ -36,7 +36,6 @@ import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -317,46 +316,6 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings
project.getLogger().lifecycle(":populating field names");
suggestFieldNames(minecraftProvider, baseTinyMappings, tinyMappings);
}
MemoryMappingTree tree = new MemoryMappingTree();
MappingReader.read(tinyMappings, tree);
tmpFixInnerClasses(tree);
try (Tiny2Writer writer = new Tiny2Writer(Files.newBufferedWriter(tinyMappings, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE), false)) {
tree.accept(writer);
}
}
private void tmpFixInnerClasses(MappingTree tree) {
int intermediaryIdx = tree.getNamespaceId("intermediary");
int namedIdx = tree.getNamespaceId("named");
for (MappingTree.ClassMapping classEntry : tree.getClasses()) {
String intermediaryName = classEntry.getDstName(intermediaryIdx);
String namedName = classEntry.getDstName(namedIdx);
// There's no mapped name
if (intermediaryName.equals(namedName)) {
// Try finding enclosing classes of an unmapped inner class that may have a mapped name we need
// to inherit
String[] path = intermediaryName.split(Pattern.quote("$"));
int parts = path.length;
for (int i = parts - 2; i >= 0; i--) {
String currentPath = String.join("$", Arrays.copyOfRange(path, 0, i + 1));
String namedParentClass = tree.mapClassName(currentPath, intermediaryIdx, namedIdx);
if (!namedParentClass.equals(currentPath)) {
String newNamedName = namedParentClass + "$" + String.join("$", Arrays.copyOfRange(path, i + 1, path.length));
if (!namedName.equals(newNamedName)) {
classEntry.setDstName(newNamedName, namedIdx);
break;
}
}
}
}
}
}
private static MemoryMappingTree readMappings(Path file) throws IOException {
@@ -475,6 +434,8 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings
Tiny2Reader.read(reader, tree);
}
inheritMappedNamesOfEnclosingClasses(tree);
try (Tiny2Writer writer = new Tiny2Writer(Files.newBufferedWriter(out, StandardCharsets.UTF_8), false)) {
tree.accept(writer);
}
@@ -482,6 +443,40 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings
project.getLogger().info(":merged mappings in " + stopwatch.stop());
}
/**
* Searches the mapping tree for inner classes with no mapped name, whose enclosing classes have mapped names.
* Currently, Yarn does not export mappings for these inner classes.
*/
private void inheritMappedNamesOfEnclosingClasses(MemoryMappingTree tree) {
int intermediaryIdx = tree.getNamespaceId("intermediary");
int namedIdx = tree.getNamespaceId("named");
// The tree does not have an index by intermediary names by default
tree.setIndexByDstNames(true);
for (MappingTree.ClassMapping classEntry : tree.getClasses()) {
String intermediaryName = classEntry.getDstName(intermediaryIdx);
String namedName = classEntry.getDstName(namedIdx);
if (intermediaryName.equals(namedName) && intermediaryName.contains("$")) {
String[] path = intermediaryName.split(Pattern.quote("$"));
int parts = path.length;
for (int i = parts - 2; i >= 0; i--) {
String currentPath = String.join("$", Arrays.copyOfRange(path, 0, i + 1));
String namedParentClass = tree.mapClassName(currentPath, intermediaryIdx, namedIdx);
if (!namedParentClass.equals(currentPath)) {
classEntry.setDstName(namedParentClass
+ "$" + String.join("$", Arrays.copyOfRange(path, i + 1, path.length)),
namedIdx);
break;
}
}
}
}
}
private MemoryMappingTree readIntermediaryTree() throws IOException {
MemoryMappingTree tree = new MemoryMappingTree();
MappingNsCompleter nsCompleter = new MappingNsCompleter(tree, Collections.singletonMap(MappingsNamespace.NAMED.toString(), MappingsNamespace.INTERMEDIARY.toString()), true);

View File

@@ -0,0 +1,71 @@
/*
* This file is part of fabric-loom, licensed under the MIT License (MIT).
*
* Copyright (c) 2021 FabricMC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package net.fabricmc.loom.util;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.RecordComponentVisitor;
import net.fabricmc.mappingio.tree.MemoryMappingTree;
public class RecordComponentFixVisitor extends ClassVisitor {
private final MemoryMappingTree mappings;
private final int intermediaryNsId;
private String owner;
private boolean hasExistingComponents = false;
public RecordComponentFixVisitor(ClassVisitor classVisitor, MemoryMappingTree mappings, int intermediaryNsId) {
super(Constants.ASM_VERSION, classVisitor);
this.mappings = mappings;
this.intermediaryNsId = intermediaryNsId;
}
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
this.owner = name;
super.visit(version, access, name, signature, superName, interfaces);
}
@Override
public RecordComponentVisitor visitRecordComponent(String name, String descriptor, String signature) {
// Should never happen, but let's be safe
hasExistingComponents = true;
return super.visitRecordComponent(name, descriptor, signature);
}
@Override
public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) {
String intermediaryName = mappings.getField(owner, name, descriptor).getName(intermediaryNsId);
if (!hasExistingComponents && intermediaryName != null && intermediaryName.startsWith("comp_")) {
super.visitRecordComponent(name, descriptor, signature);
}
return super.visitField(access, name, descriptor, signature, value);
}
}

View File

@@ -37,7 +37,9 @@ import dev.architectury.tinyremapper.TinyRemapper;
import org.gradle.api.Project;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
import net.fabricmc.mappingio.tree.MappingTree;
import net.fabricmc.mappingio.tree.MemoryMappingTree;
/**
* Contains shortcuts to create tiny remappers using the mappings accessibly to the project.
@@ -58,9 +60,13 @@ public final class TinyRemapperHelper {
}
public static TinyRemapper getTinyRemapper(Project project, String fromM, String toM) throws IOException {
return getTinyRemapper(project, fromM, toM, false);
}
public static TinyRemapper getTinyRemapper(Project project, String fromM, String toM, boolean fixRecords) throws IOException {
LoomGradleExtension extension = LoomGradleExtension.get(project);
TinyRemapper remapper = _getTinyRemapper(project);
TinyRemapper remapper = _getTinyRemapper(project, fixRecords);
remapper.replaceMappings(ImmutableSet.of(
TinyRemapperHelper.create(extension.isForge() ? extension.getMappingsProvider().getMappingsWithSrg() : extension.getMappingsProvider().getMappings(), fromM, toM, true),
out -> TinyRemapperHelper.JSR_TO_JETBRAINS.forEach(out::acceptClass)
@@ -68,8 +74,15 @@ public final class TinyRemapperHelper {
return remapper;
}
public static TinyRemapper _getTinyRemapper(Project project) throws IOException {
public static TinyRemapper _getTinyRemapper(Project project, boolean fixRecords) throws IOException {
LoomGradleExtension extension = LoomGradleExtension.get(project);
MemoryMappingTree mappingTree = extension.getMappingsProvider().getMappings();
if (fixRecords && !mappingTree.getSrcNamespace().equals(fromM)) {
throw new IllegalStateException("Mappings src namespace must match remap src namespace");
}
int intermediaryNsId = mappingTree.getNamespaceId(MappingsNamespace.INTERMEDIARY.toString());
TinyRemapper.Builder builder = TinyRemapper.newRemapper()
.renameInvalidLocals(true)
@@ -88,6 +101,13 @@ public final class TinyRemapperHelper {
}
return builder.invalidLvNamePattern(MC_LV_PATTERN)
.extraPreApplyVisitor((cls, next) -> {
if (fixRecords && !cls.isRecord() && "java/lang/Record".equals(cls.getSuperName())) {
return new RecordComponentFixVisitor(next, mappingTree, intermediaryNsId);
}
return next;
})
.build();
}

View File

@@ -15,7 +15,7 @@ dependencies {
minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
//modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
}
tasks.withType(JavaCompile).configureEach {

View File

@@ -1,8 +1,8 @@
org.gradle.jvmargs=-Xmx1G
minecraft_version=1.17.1
yarn_mappings=1.17.1+build.29
loader_version=0.11.6
minecraft_version=21w37a
yarn_mappings=21w37a+build.5
loader_version=0.11.7
fabric_version=0.37.1+1.17
mod_version = 1.0.0