Skip to content

Commit

Permalink
Merge upstream
Browse files Browse the repository at this point in the history
  • Loading branch information
NebelNidas committed Jan 17, 2025
2 parents 8b4431b + e8acce3 commit b36e543
Show file tree
Hide file tree
Showing 207 changed files with 7,074 additions and 2,282 deletions.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* text=auto eol=lf
*.bat text eol=crlf
28 changes: 28 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,38 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
- Made `OuterClassNamePropagator` configurable
- Made Enigma writer always output destination names if visited explicitly, establishing consistency across all writers
- Added a simplified `MappingNsCompleter` constructor for completing all destination names with the source names
- Added translatable `MappingFormat#getName()`

## [0.7.1] - 2025-01-07
- Restored the ability to read source-namespace-only mapping files, even if not spec-compliant

## [0.7.0] - 2025-01-01
- Added IntelliJ IDEA migration map reader and writer
- Added `MappingFormat#features()` to allow for more fine-grained programmatic querying of format capabilities
- Added tests to validate our writer outputs against 3rd-party readers
- Overhauled the internal `ColumnFileReader` to behave more consistently
- Made `VisitOrder#createByName` use alphanumeric and nest-aware sorting
- Made handling of the `NEEDS_MULTIPLE_PASSES` flag more consistent, reducing memory usage in a few cases
- Made some internal methods in Enigma and TSRG readers actually private
- Renamed `OuterClassNameInheritingVisitor` to `OuterClassNamePropagator` and made its constructor public
- Made all writers for formats which can't represent empty destination names skip such elements entirely, unless the format is hierarchical and mapped child elements are present
- Adjusted some readers to make sure that elements aren't visited multiple times with the same data
- Added missing visit calls to multiple readers
- Added safeguards to `MemoryMappingTree` preventing external data modification during an ongoing visitation pass
- Clearly defined tree-API contracts regarding returned collections' mutability
- Fixed `MemoryMappingTree#reset()` to actually reset all its internal state related to the current visitation pass
- Fixed and improved `MemoryMappingTree`'s merging capabilities:
- Fixed broken tree-API member mapping merging
- Fixed existing entries' data not getting overridden when merging elements via tree-API
- Fixed NPE when visiting with flipped namespaces ([issue 68](https://github.com/FabricMC/mapping-io/issues/68))
- Made merging with flipped namespaces actually work and handle both names and descriptors
- Fixed potentially incorrect descriptor computation by delaying until all classes are present and merged
- Fixed duplicate mapping definitions not being handled correctly in multiple readers
- Fixed incorrect handling of class repackaging in JOBF reader and writer
- Removed ASM dependency from core project

## [0.6.1] - 2024-04-15
- Fixed CSRG and JAM writers sometimes skipping elements whose parents have incomplete destination names
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ MappingReader.read(inputPath, /* optional */ inputFormat,
```

The above example reads mappings from the input path directly into a `MappingWriter`, writing all contents to disk in the specified format.
Keep in mind that the conversion process might be lossy if the two formats' feature sets differ; see the comparison table [here](./src/main/java/net/fabricmc/mappingio/format/MappingFormat.java) for more details.
Keep in mind that the conversion process might be lossy if the two formats' feature sets differ; see the comparison table [here](https://fabricmc.net/wiki/documentation:mapping_formats) for more details.

You can also read into a tree first:
```java
Expand All @@ -33,7 +33,7 @@ For further information, please consult the project's Javadocs.


### Maven
Mapping-IO is available from the [FabricMC Maven](https://maven.fabricmc.net/net/fabricmc/mapping-io), version 0.4.2 and onwards can also be found on Maven Central.
Mapping-IO is available from the [FabricMC Maven](https://maven.fabricmc.net/net/fabricmc/mapping-io). Version 0.4.2 and onward can also be found on Maven Central.

Gradle snippet:
```gradle
Expand All @@ -42,6 +42,6 @@ repositories {
}
dependencies {
api 'net.fabricmc:mapping-io:${mappingio_version}'
implementation "net.fabricmc:mapping-io:${mappingio_version}"
}
```
45 changes: 35 additions & 10 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
plugins {
id "com.diffplug.spotless" version "6.22.0" apply false
id "me.modmuss50.remotesign" version "0.4.0" apply false
id "com.diffplug.spotless" apply false
id "me.modmuss50.remotesign" apply false
}

def ENV = System.getenv()
Expand All @@ -25,25 +25,37 @@ allprojects {
toolVersion = project.checkstyle_tool_version
}

spotless {
lineEndings = com.diffplug.spotless.LineEnding.UNIX

java {
licenseHeaderFile(rootProject.file("HEADER")).yearSeparator(", ")
removeUnusedImports()
importOrder('java', 'javax', '', 'net.fabricmc')
indentWithTabs()
trimTrailingWhitespace()
targetExclude(
'src/test/java/net/fabricmc/mappingio/test/lib/**/*.java',
'src/main/java/net/fabricmc/mappingio/tree/AlphanumericComparator.java')
}
}

repositories {
mavenCentral()
}

dependencies {
implementation "org.ow2.asm:asm:${project.asm_version}"
compileOnly "org.jetbrains:annotations:${project.jetbrains_annotations_version}"

testImplementation "net.neoforged:srgutils:${srgutils_version}"
testImplementation "org.cadixdev:lorenz:${lorenz_version}"
testImplementation "org.cadixdev:lorenz-io-enigma:${lorenz_version}"
testImplementation "org.cadixdev:lorenz-io-jam:${lorenz_version}"
testImplementation "org.junit.jupiter:junit-jupiter:${junit_jupiter_version}"
testRuntimeOnly "org.junit.platform:junit-platform-launcher"
testCompileOnly "org.jetbrains:annotations:${project.jetbrains_annotations_version}"
}

spotless {
java {
licenseHeaderFile(rootProject.file("HEADER")).yearSeparator(", ")
}
}

java {
withSourcesJar()
withJavadocJar()
Expand All @@ -58,9 +70,15 @@ allprojects {

javadoc {
failOnError = false

options {
// Disable the crazy super-strict doclint tool in Java 8
addStringOption('Xdoclint:none', '-quiet')

tags(
'apiNote:a:API Note:',
'implSpec:a:Implementation Requirements:',
'implNote:a:Implementation Note:')
}
}

Expand Down Expand Up @@ -180,8 +198,15 @@ jar {
}
}

tasks.register("generateTestMappings", JavaExec) {
dependsOn("testClasses")
classpath = sourceSets.test.runtimeClasspath
mainClass = 'net.fabricmc.mappingio.test.TestFileUpdater'
args = [file('src/test/resources/').getAbsolutePath()]
}

// A task to ensure that the version being released has not already been released.
task checkVersion {
tasks.register("checkVersion") {
doFirst {
def xml = new URL("https://maven.fabricmc.net/net/fabricmc/mapping-io/maven-metadata.xml").text
def metadata = new XmlSlurper().parseText(xml)
Expand Down
20 changes: 14 additions & 6 deletions checkstyle.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
if <something> is a space, indicating a formatting error or ' */', it'll ignore the instance
if <something> is a tab, indicating a continued line, it'll ignore the instance
<control statement> is 'if', 'do', 'while', 'for', 'try' or nothing (instance initializer block)
- first \n: with positive lookbehind (?<=\n) to move the error marker to a more reasonable place
- capture tabs for <indentation>, later referenced via \1
- remaining preceding line as a non-comment (doesn't start with '/', '//', ' ' or '\t') or multiple lines where all but the first are a single line comment with the same indentation
Expand All @@ -61,6 +62,13 @@
</module>

<module name="TreeWalker">
<!-- Allow "//CHECKSTYLE.OFF: <InspectionName>" and "//CHECKSTYLE.ON: <InspectionName>" pairs to toggle some inspections -->
<module name="SuppressionCommentFilter">
<property name="offCommentFormat" value="CHECKSTYLE.OFF\: ([\w\|]+)"/>
<property name="onCommentFormat" value="CHECKSTYLE.ON\: ([\w\|]+)"/>
<property name="checkFormat" value="$1"/>
</module>

<!-- Ensure all imports are ship shape -->
<module name="AvoidStarImport"/>
<module name="IllegalImport"/>
Expand All @@ -69,7 +77,7 @@

<module name="ImportOrder">
<property name="groups" value="java,javax,*,net.minecraft,net.fabricmc"/>
<property name="ordered" value="false"/><!-- the plugin orders alphabetically without considering separators.. -->
<property name="ordered" value="true"/>
<property name="separated" value="true"/>
<property name="option" value="top"/>
<property name="sortStaticImportsAlphabetically" value="true"/>
Expand Down Expand Up @@ -162,10 +170,10 @@
<module name="AtclauseOrder">
<property name="tagOrder" value="@param,@return,@throws,@deprecated"/>
</module>
</module>

<module name="SuppressionSingleFilter">
<property name="files" value="net[\\/]fabricmc[\\/]loader[\\/]lib[\\/]"/>
<property name="checks" value=".*"/>
<!-- Prevent var for all cases other than new instance creation -->
<module name="MatchXpath">
<property name="query" value="//VARIABLE_DEF[./TYPE/IDENT[@text='var'] and not(./ASSIGN/EXPR/LITERAL_NEW)]"/>
</module>
</module>
</module>
</module>
18 changes: 12 additions & 6 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
# Gradle Properties
org.gradle.jvmargs = -Xmx2G

# Gradle Plugins
spotless_version = 6.25.0
remotesign_version = 0.4.0
checkstyle_tool_version = 10.21.1

# Project properties
version = 0.6.1
version = 0.7.1

# Dependencies
asm_version = 9.6
tiny_remapper_version = 0.8.0
jetbrains_annotations_version = 24.0.1
checkstyle_tool_version = 10.12.4
junit_jupiter_version = 5.10.0
asm_version = 9.7.1
tiny_remapper_version = 0.10.4
jetbrains_annotations_version = 26.0.1
junit_jupiter_version = 5.11.4
srgutils_version = 1.0.9
lorenz_version = 0.5.8
Original file line number Diff line number Diff line change
Expand Up @@ -19,63 +19,106 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import java.io.IOException;

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.objectweb.asm.Type;

import net.fabricmc.mappingio.TestHelper;
import net.fabricmc.mappingio.test.TestMappings;
import net.fabricmc.mappingio.tree.MappingTree;
import net.fabricmc.mappingio.tree.MappingTree.ClassMapping;
import net.fabricmc.mappingio.tree.MappingTree.FieldMapping;
import net.fabricmc.mappingio.tree.MappingTree.MethodMapping;
import net.fabricmc.mappingio.tree.MemoryMappingTree;

public class MappingTreeRemapperTest {
private static final String cls1SrcName = "class_1";
private static final String cls3SrcName = "class_3";
private static final String fld1SrcName = "field_1";
private static final String mth1SrcName = "method_1";
private static String srcNs;
private static String dstNs;
private static String cls1DstName;
private static String cls3DstName;
private static String fld1SrcDesc;
private static String fld1DstName;
private static String mth1SrcDesc;
private static String mth1DstName;
private static MappingTree mappingTree;
private static MappingTreeRemapper remapper;

@BeforeAll
public static void setup() {
mappingTree = TestHelper.createTestTree();
remapper = new MappingTreeRemapper(mappingTree, "source", "target");
public static void setup() throws IOException {
mappingTree = TestMappings.generateValid(new MemoryMappingTree());
srcNs = mappingTree.getSrcNamespace();
dstNs = mappingTree.getDstNamespaces().get(0);

remapper = new MappingTreeRemapper(mappingTree, srcNs, dstNs);

ClassMapping cls1 = mappingTree.getClass(cls1SrcName);
ClassMapping cls3 = mappingTree.getClass(cls3SrcName);
cls1DstName = cls1.getDstName(0);
cls3DstName = cls3.getDstName(0);

FieldMapping fld1 = cls1.getField(fld1SrcName, null);
fld1SrcDesc = fld1.getSrcDesc();
fld1DstName = fld1.getDstName(0);

MethodMapping mth1 = cls1.getMethod(mth1SrcName, null);
mth1SrcDesc = mth1.getSrcDesc();
mth1DstName = mth1.getDstName(0);
}

@Test
public void testInvalidNamespaces() {
assertThrows(IllegalArgumentException.class, () -> new MappingTreeRemapper(mappingTree, "unknown", "target"),
assertThrows(IllegalArgumentException.class, () -> new MappingTreeRemapper(mappingTree, "unknown", dstNs),
"must throw on missing source namespace");
assertThrows(IllegalArgumentException.class, () -> new MappingTreeRemapper(mappingTree, "source", "unknown"),
assertThrows(IllegalArgumentException.class, () -> new MappingTreeRemapper(mappingTree, srcNs, "unknown"),
"must throw on missing target namespace");
}

@Test
public void testMapClass() {
assertEquals("class1Ns0Rename", remapper.map("class_1"));
assertEquals(cls1DstName, remapper.map(cls1SrcName));
}

@Test
public void testMapMethod() {
assertEquals("method1Ns0Rename", remapper.mapMethodName("class_1", "method_1", "()I"));
assertEquals(mth1DstName, remapper.mapMethodName(cls1SrcName, mth1SrcName, mth1SrcDesc));
}

@Test
public void testMapField() {
assertEquals("field1Ns0Rename", remapper.mapFieldName("class_1", "field_1", "I"));
assertEquals(fld1DstName, remapper.mapFieldName(cls1SrcName, fld1SrcName, fld1SrcDesc));
}

@Test
public void testMapRecordComponent() {
// Record components are remapped as fields.
assertEquals("field1Ns0Rename", remapper.mapRecordComponentName("class_1", "field_1", "I"));
assertEquals(fld1DstName, remapper.mapRecordComponentName(cls1SrcName, fld1SrcName, fld1SrcDesc));
}

@Test
public void testMapDesc() {
assertEquals("Lclass3Ns0Rename;", remapper.mapDesc("Lclass_3;"));
assertEquals("()Lclass1Ns0Rename;", remapper.mapMethodDesc("()Lclass_1;"));
assertEquals(clsDesc(cls1DstName), remapper.mapDesc(clsDesc(cls1SrcName)));
assertEquals(mthDesc(cls3DstName), remapper.mapMethodDesc(mthDesc(cls3SrcName)));
}

@Test
public void testMapType() {
Type fieldType = Type.getType("Lclass_3;");
Type methodType = Type.getMethodType("()Lclass_1;");
assertEquals(Type.getType("Lclass3Ns0Rename;"), remapper.mapValue(fieldType));
assertEquals(Type.getMethodType("()Lclass1Ns0Rename;"), remapper.mapValue(methodType));
Type fieldType = Type.getType(clsDesc(cls3SrcName));
Type methodType = Type.getMethodType(mthDesc(cls1SrcName));

assertEquals(Type.getType(clsDesc(cls3DstName)), remapper.mapValue(fieldType));
assertEquals(Type.getMethodType(mthDesc(cls1DstName)), remapper.mapValue(methodType));
}

private String clsDesc(String name) {
return "L" + name + ";";
}

private String mthDesc(String name) {
return "()L" + name + ";";
}
}
4 changes: 4 additions & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ pluginManagement {
mavenCentral()
gradlePluginPortal()
}
plugins {
id 'com.diffplug.spotless' version "${spotless_version}"
id 'me.modmuss50.remotesign' version "${remotesign_version}"
}
}

rootProject.name = 'mapping-io'
Expand Down
Loading

0 comments on commit b36e543

Please sign in to comment.