Skip to content

Commit

Permalink
Close #123: Support Parchment
Browse files Browse the repository at this point in the history
Now can initialize ClassMapping without an initial Mapping
More PairedMapping constructors
Bump REWH Logging to 0.1
  • Loading branch information
XiaoPangxie732 committed Aug 25, 2024
1 parent 468daae commit 3aefb43
Show file tree
Hide file tree
Showing 24 changed files with 559,801 additions and 36 deletions.
14 changes: 14 additions & 0 deletions extensions/mixins-remapper/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,18 @@
</parent>

<artifactId>mixins-remapper</artifactId>
<name>MinecraftDecompiler Extensions - Mixin Remappers</name>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
48 changes: 48 additions & 0 deletions extensions/parchment/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.maxpixel.mcd-extensions</groupId>
<artifactId>parent</artifactId>
<version>4.0-SNAPSHOT</version>
</parent>

<artifactId>parchment</artifactId>
<name>MinecraftDecompiler Extensions - Parchment Mappings</name>

<dependencies>
<dependency>
<groupId>cn.maxpixel.minecraft-decompiler</groupId>
<artifactId>api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package cn.maxpixel.mcdecompiler.mapping.parchment;

public record FormatVersion(int major, int minor, int patch) {
public static FormatVersion CURRENT = new FormatVersion(1, 1, 0);

public FormatVersion {
if (major < 0) throw new IllegalArgumentException("Major version " + major + "must not be negative");
if (minor < 0) throw new IllegalArgumentException("Minor version " + major + "must not be negative");
if (patch < 0) throw new IllegalArgumentException("Patch version " + major + "must not be negative");
}

public static FormatVersion from(String version) {
String[] parts = version.split("\\.");
if (parts.length < 2) throw new IllegalArgumentException("Expected at least 2 tokens for version " + version);
if (parts.length > 3) throw new IllegalArgumentException("Expected at most 3 tokens for version " + version);
return new FormatVersion(
Integer.parseInt(parts[0]),
Integer.parseInt(parts[1]),
parts.length == 3 ? Integer.parseInt(parts[2]) : 0
);
}

public boolean compatibleWith(FormatVersion v) {
return major == v.major;
}

@Override
public String toString() {
return major + "." + minor + '.' + patch;// need at least 1 string to make sure this is string concatenation
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package cn.maxpixel.mcdecompiler.mapping.parchment;

import cn.maxpixel.mcdecompiler.api.extension.Extension;
import cn.maxpixel.mcdecompiler.api.extension.OptionRegistry;
import cn.maxpixel.mcdecompiler.mapping.format.MappingFormats;
import org.jetbrains.annotations.NotNull;

public class ParchmentExtension implements Extension {
public static final String NAME = "parchment";

@NotNull
@Override
public String getName() {
return NAME;
}

@Override
public void onRegistering(OptionRegistry.Registrar optionRegistrar) {
MappingFormats.registerMappingFormat(ParchmentMappingFormat.INSTANCE);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package cn.maxpixel.mcdecompiler.mapping.parchment;

import cn.maxpixel.mcdecompiler.mapping.PairedMapping;
import cn.maxpixel.mcdecompiler.mapping.collection.ClassifiedMapping;
import cn.maxpixel.mcdecompiler.mapping.format.MappingFormat;
import org.jetbrains.annotations.NotNull;

import java.io.BufferedReader;
import java.util.Objects;

public enum ParchmentMappingFormat implements MappingFormat.Classified<PairedMapping> {
INSTANCE;
public static final String KEY_NAME = "name";
public static final String KEY_JAVADOC = "javadoc";
public static final String KEY_DESCRIPTOR = "descriptor";
public static final String KEY_VERSION = "version";
public static final String KEY_PACKAGES = "packages";
public static final String KEY_CLASSES = "classes";
public static final String KEY_FIELDS = "fields";
public static final String KEY_METHODS = "methods";
public static final String KEY_INDEX = "index";
public static final String KEY_PARAMETERS = "parameters";

@Override
public @NotNull String getName() {
return ParchmentExtension.NAME;
}

@Override
public char getCommentChar() {
return '\0';
}

@Override
public @NotNull ParchmentMappingProcessor getProcessor() {
return ParchmentMappingProcessor.INSTANCE;
}

@Override
public @NotNull ParchmentMappingGenerator getGenerator() {
return ParchmentMappingGenerator.INSTANCE;
}

@Override
public @NotNull ClassifiedMapping<PairedMapping> read(@NotNull BufferedReader reader) {
return getProcessor().process(Objects.requireNonNull(reader));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
package cn.maxpixel.mcdecompiler.mapping.parchment;

import cn.maxpixel.mcdecompiler.common.util.Utils;
import cn.maxpixel.mcdecompiler.mapping.PairedMapping;
import cn.maxpixel.mcdecompiler.mapping.collection.ClassMapping;
import cn.maxpixel.mcdecompiler.mapping.collection.ClassifiedMapping;
import cn.maxpixel.mcdecompiler.mapping.component.Descriptor;
import cn.maxpixel.mcdecompiler.mapping.component.Documented;
import cn.maxpixel.mcdecompiler.mapping.component.LocalVariableTable;
import cn.maxpixel.mcdecompiler.mapping.format.MappingFormat;
import cn.maxpixel.mcdecompiler.mapping.generator.MappingGenerator;
import cn.maxpixel.mcdecompiler.mapping.remapper.ClassifiedMappingRemapper;
import com.google.gson.stream.JsonWriter;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import it.unimi.dsi.fastutil.objects.ObjectList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.IOException;
import java.io.Writer;

import static cn.maxpixel.mcdecompiler.mapping.parchment.ParchmentMappingFormat.*;

public enum ParchmentMappingGenerator implements MappingGenerator.Classified<PairedMapping> {
INSTANCE;

@Override
public ObjectList<String> generate(ClassifiedMapping<PairedMapping> mappings, @Nullable ClassifiedMappingRemapper remapper) {
StringListWriter slw = new StringListWriter();// No specialized version of returning String because it's not worth it
try (JsonWriter writer = new JsonWriter(slw)) {
writer.setIndent(" ");// 2 spaces
writer.beginObject()
.name(KEY_VERSION)
.value(FormatVersion.CURRENT.toString());
if (!mappings.packages.isEmpty()) writePackages(mappings, writer);
if (!mappings.classes.isEmpty()) writeClasses(mappings, writer);
writer.endObject();
} catch (IOException e) {
throw Utils.wrapInRuntime(e);
}
return slw.list;
}

private static void writeClasses(ClassifiedMapping<PairedMapping> mappings, JsonWriter writer) throws IOException {
writer.name(KEY_CLASSES).beginArray();
for (@NotNull ClassMapping<@NotNull PairedMapping> cm : mappings.classes) {
writer.beginObject()
.name(KEY_NAME)
.value(cm.mapping.unmappedName);
writeDoc(cm.mapping, writer);
var fields = cm.getFields();
if (!fields.isEmpty()) {
writer.name(KEY_FIELDS).beginArray();
for (@NotNull PairedMapping field : fields) {
writer.beginObject()
.name(KEY_NAME)
.value(field.unmappedName)
.name(KEY_DESCRIPTOR)
.value(field.getComponent(Descriptor.class).unmappedDescriptor);
writeDoc(field, writer);
writer.endObject();
}
writer.endArray();
}
var methods = cm.getMethods();
if (!methods.isEmpty()) {
writer.name(KEY_METHODS).beginArray();
for (@NotNull PairedMapping method : methods) {
writer.beginObject()
.name(KEY_NAME)
.value(method.unmappedName)
.name(KEY_DESCRIPTOR)
.value(method.getComponent(Descriptor.class).unmappedDescriptor);
writeDoc(method, writer);
writeParams(writer, method);
writer.endObject();
}
writer.endArray();
}
writer.endObject();
}
writer.endArray();
}

private static void writeParams(JsonWriter writer, @NotNull PairedMapping method) throws IOException {
var params = method.getComponent(LocalVariableTable.Paired.class);
if (params != null && !params.isEmpty()) {
writer.name(KEY_PARAMETERS).beginArray();
for (var indexes = params.getLocalVariableIndexes().iterator(); indexes.hasNext(); ) {
int i = indexes.nextInt();
PairedMapping param = params.getLocalVariable(i);
writer.beginObject()
.name(KEY_INDEX)
.jsonValue(Integer.toString(i))
.name(KEY_NAME)
.value(param.unmappedName);
Documented doc = param.getComponent(Documented.class);
if (doc != null && !doc.contents.isEmpty()) {
writer.name(KEY_JAVADOC).value(doc.getContentString());
}
writer.endObject();
}
writer.endArray();
}
}

private static void writeDoc(PairedMapping m, JsonWriter writer) throws IOException {
Documented doc = m.getComponent(Documented.class);
if (doc != null && !doc.contents.isEmpty()) {
writer.name(KEY_JAVADOC)
.beginArray();
for (String c : doc.contents) writer.value(c);
writer.endArray();
}
}

private static void writePackages(ClassifiedMapping<PairedMapping> mappings, JsonWriter writer) throws IOException {
writer.name(KEY_PACKAGES).beginArray();
for (@NotNull PairedMapping pkg : mappings.packages) {
writer.beginObject()
.name(KEY_NAME)
.value(pkg.unmappedName);
writeDoc(pkg, writer);
writer.endObject();
}
writer.endArray();
}

@Override
public MappingFormat<PairedMapping, ClassifiedMapping<PairedMapping>> getFormat() {
return ParchmentMappingFormat.INSTANCE;
}

private static class StringListWriter extends Writer {
private final ObjectArrayList<String> list = new ObjectArrayList<>();
private final StringBuilder sb = new StringBuilder();

@Override
public void write(int c) {
if (c == '\n') {// JsonWriter only writes newline here
list.add(sb.toString());
sb.setLength(0);
} else sb.append((char) c);
}

@Override
public void write(char @NotNull [] cbuf) {
sb.append(cbuf);
}

@Override
public void write(@NotNull String str) {
sb.append(str);
}

@Override
public void write(@NotNull String str, int off, int len) {
sb.append(str, off, off + len);
}

@Override
public void write(char @NotNull [] cbuf, int off, int len) {
sb.append(cbuf, off, len);
}

@Override
public void flush() {
}

@Override
public void close() {
list.add(sb.toString());
}
}
}
Loading

0 comments on commit 3aefb43

Please sign in to comment.