diff options
author | Jonas Herzig <me@johni0702.de> | 2019-06-17 17:20:04 +0200 |
---|---|---|
committer | Jonas Herzig <me@johni0702.de> | 2019-06-23 14:40:25 +0200 |
commit | 14c120609607cd9f74cfd411cfae80017ea4c4ab (patch) | |
tree | a857151fcd1a3c8a34ec2fec0cd157644647ee7c | |
parent | 18a9a9d7b048e11981d2e3bf47af17e024e0ebef (diff) | |
download | Remap-14c120609607cd9f74cfd411cfae80017ea4c4ab.tar.gz Remap-14c120609607cd9f74cfd411cfae80017ea4c4ab.tar.bz2 Remap-14c120609607cd9f74cfd411cfae80017ea4c4ab.zip |
Use lorenz library for proper Mapping model
7 files changed, 328 insertions, 134 deletions
diff --git a/build.gradle b/build.gradle index 35aa3df..921cf96 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ sourceCompatibility = '1.8' targetCompatibility = '1.8' group = 'com.github.replaymod' -version = '1.0-SNAPSHOT' +version = 'SNAPSHOT' repositories { mavenCentral() @@ -15,6 +15,7 @@ repositories { dependencies { compile 'org.jetbrains.kotlin:kotlin-compiler:1.3.31' + compile 'org.cadixdev:lorenz:0.5.0' } jar { diff --git a/src/main/java/com/replaymod/gradle/remap/PsiMapper.java b/src/main/java/com/replaymod/gradle/remap/PsiMapper.java index 17d0783..c1b2d41 100644 --- a/src/main/java/com/replaymod/gradle/remap/PsiMapper.java +++ b/src/main/java/com/replaymod/gradle/remap/PsiMapper.java @@ -18,7 +18,11 @@ import com.intellij.psi.PsiPackage; import com.intellij.psi.PsiQualifiedNamedElement; import com.intellij.psi.PsiSwitchLabelStatement; import com.intellij.psi.PsiTypeElement; -import com.replaymod.gradle.remap.Transformer.Mapping; +import org.cadixdev.bombe.type.signature.MethodSignature; +import org.cadixdev.lorenz.MappingSet; +import org.cadixdev.lorenz.model.ClassMapping; +import org.cadixdev.lorenz.model.Mapping; +import org.cadixdev.lorenz.model.MethodMapping; import java.util.ArrayDeque; import java.util.Arrays; @@ -27,6 +31,8 @@ import java.util.HashMap; import java.util.Map; import java.util.TreeMap; +import static com.replaymod.gradle.remap.PsiUtils.getSignature; + class PsiMapper { private static final String CLASS_MIXIN = "org.spongepowered.asm.mixin.Mixin"; private static final String CLASS_ACCESSOR = "org.spongepowered.asm.mixin.gen.Accessor"; @@ -34,17 +40,23 @@ class PsiMapper { private static final String CLASS_INJECT = "org.spongepowered.asm.mixin.injection.Inject"; private static final String CLASS_REDIRECT = "org.spongepowered.asm.mixin.injection.Redirect"; - private final Map<String, Mapping> map; - private final Map<String, Mapping> mixinMappings = new HashMap<>(); + private final MappingSet map; + private final Map<String, ClassMapping<?, ?>> mixinMappings = new HashMap<>(); private final PsiFile file; private boolean error; private TreeMap<TextRange, String> changes = new TreeMap<>(Comparator.comparing(TextRange::getStartOffset)); - PsiMapper(Map<String, Mapping> map, PsiFile file) { + PsiMapper(MappingSet map, PsiFile file) { this.map = map; this.file = file; } + private void error(PsiElement at, String message) { + int line = StringUtil.offsetToLineNumber(file.getText(), at.getTextOffset()); + System.err.println(file.getName() + ":" + line + ": " + message); + error = true; + } + private void replace(PsiElement e, String with) { changes.put(e.getTextRange(), with); } @@ -87,12 +99,12 @@ class PsiMapper { if (declaringClass == null) return; String name = declaringClass.getQualifiedName(); if (name == null) return; - Mapping mapping = this.mixinMappings.get(name); + ClassMapping<?, ?> mapping = this.mixinMappings.get(name); if (mapping == null) { - mapping = map.get(name); + mapping = map.getClassMapping(name).orElse(null); } if (mapping == null) return; - String mapped = mapping.fields.get(field.getName()); + String mapped = mapping.getFieldMapping(field.getName()).map(Mapping::getDeobfuscatedName).orElse(null); if (mapped == null || mapped.equals(field.getName())) return; replaceIdentifier(expr, mapped); @@ -100,20 +112,20 @@ class PsiMapper { && !((PsiJavaCodeReferenceElement) expr).isQualified() // qualified access is fine && !isSwitchCase(expr) // referencing constants in case statements is fine ) { - int line = StringUtil.offsetToLineNumber(file.getText(), expr.getTextOffset()); - System.err.println(file.getName() + ":" + line + ": Implicit member reference to remapped field \"" + field.getName() + "\". " + + error(expr, "Implicit member reference to remapped field \"" + field.getName() + "\". " + "This can cause issues if the remapped reference becomes shadowed by a local variable and is therefore forbidden. " + "Use \"this." + field.getName() + "\" instead."); - error = true; } } private void map(PsiElement expr, PsiMethod method) { + if (method.isConstructor()) return; + PsiClass declaringClass = method.getContainingClass(); if (declaringClass == null) return; ArrayDeque<PsiClass> parentQueue = new ArrayDeque<>(); parentQueue.offer(declaringClass); - Mapping mapping = null; + ClassMapping<?, ?> mapping = null; String name = declaringClass.getQualifiedName(); if (name != null) { @@ -121,7 +133,7 @@ class PsiMapper { } while (true) { if (mapping != null) { - String mapped = mapping.methods.get(method.getName()); + String mapped = mapping.getMethodMapping(getSignature(method)).map(Mapping::getDeobfuscatedName).orElse(null); if (mapped != null) { if (!mapped.equals(method.getName())) { replaceIdentifier(expr, mapped); @@ -144,7 +156,7 @@ class PsiMapper { name = declaringClass.getQualifiedName(); if (name == null) continue; - mapping = map.get(name); + mapping = map.getClassMapping(name).orElse(null); } } } @@ -152,10 +164,11 @@ class PsiMapper { private void map(PsiElement expr, PsiQualifiedNamedElement resolved) { String name = resolved.getQualifiedName(); if (name == null) return; - Mapping mapping = map.get(name); + ClassMapping<?, ?> mapping = map.getClassMapping(name).orElse(null); if (mapping == null) return; - String mapped = mapping.newName; + String mapped = mapping.getDeobfuscatedName(); if (mapped.equals(name)) return; + mapped = mapped.replace('/', '.'); if (expr.getText().equals(name)) { replace(expr, mapped); @@ -189,7 +202,7 @@ class PsiMapper { return null; } - private void remapAccessors(Mapping mapping) { + private void remapAccessors(ClassMapping<?, ?> mapping) { file.accept(new JavaRecursiveElementVisitor() { @Override public void visitMethod(PsiMethod method) { @@ -218,7 +231,7 @@ class PsiMapper { throw new IllegalArgumentException("Cannot determine accessor target for " + method); } - String mapped = mapping.fields.get(target); + String mapped = mapping.getFieldMapping(target).map(Mapping::getDeobfuscatedName).orElse(null); if (mapped != null && !mapped.equals(target)) { // Update accessor target String parameterList; @@ -235,7 +248,7 @@ class PsiMapper { }); } - private void remapInjectsAndRedirects(Mapping mapping) { + private void remapInjectsAndRedirects(ClassMapping<?, ?> mapping) { file.accept(new JavaRecursiveElementVisitor() { @Override public void visitMethod(PsiMethod method) { @@ -250,7 +263,21 @@ class PsiMapper { // Note: mixin supports multiple targets, we do not (yet) String literalValue = attribute.getLiteralValue(); if (literalValue == null) continue; - String mapped = mapping.methods.get(literalValue); + String mapped; + if (literalValue.contains("(")) { + mapped = mapping.getMethodMapping(MethodSignature.of(literalValue)).map(Mapping::getDeobfuscatedName).orElse(null); + } else { + mapped = null; + for (MethodMapping methodMapping : mapping.getMethodMappings()) { + if (methodMapping.getObfuscatedName().equals(literalValue)) { + String name = methodMapping.getDeobfuscatedName(); + if (mapped != null && !mapped.equals(name)) { + error(attribute, "Ambiguous mixin method \"" + literalValue + "\" maps to \"" + mapped + "\" and \"" + name + "\""); + } + mapped = name; + } + } + } if (mapped != null && !mapped.equals(literalValue)) { PsiAnnotationMemberValue value = attribute.getValue(); assert value != null; @@ -261,12 +288,12 @@ class PsiMapper { }); } - private Mapping remapInternalType(String internalType, StringBuilder result) { + private ClassMapping<?, ?> remapInternalType(String internalType, StringBuilder result) { if (internalType.charAt(0) == 'L') { String type = internalType.substring(1, internalType.length() - 1).replace('/', '.'); - Mapping mapping = map.get(type); + ClassMapping<?, ?> mapping = map.getClassMapping(type).orElse(null); if (mapping != null) { - result.append('L').append(mapping.newName.replace('.', '/')).append(';'); + result.append('L').append(mapping.getFullDeobfuscatedName()).append(';'); return mapping; } } @@ -287,10 +314,14 @@ class PsiMapper { String returnType = signature.substring(argsEnd + 1); StringBuilder builder = new StringBuilder(signature.length() + 32); - Mapping mapping = remapInternalType(owner, builder); + ClassMapping<?, ?> mapping = remapInternalType(owner, builder); String mapped = null; if (mapping != null) { - mapped = (method ? mapping.methods : mapping.fields).get(name); + mapped = (method + ? mapping.getMethodMapping(MethodSignature.of(signature.substring(ownerEnd + 1))) + : mapping.getFieldMapping(name)) + .map(Mapping::getDeobfuscatedName) + .orElse(null); } builder.append(mapped != null ? mapped : name); if (method) { @@ -350,16 +381,18 @@ class PsiMapper { PsiClass target = getMixinTarget(annotation); if (target == null) return; + String qualifiedName = target.getQualifiedName(); + if (qualifiedName == null) return; - Mapping mapping = map.get(target.getQualifiedName()); + ClassMapping<?, ?> mapping = map.getClassMapping(qualifiedName).orElse(null); if (mapping == null) return; mixinMappings.put(psiClass.getQualifiedName(), mapping); - if (!mapping.fields.isEmpty()) { + if (!mapping.getFieldMappings().isEmpty()) { remapAccessors(mapping); } - if (!mapping.methods.isEmpty()) { + if (!mapping.getMethodMappings().isEmpty()) { remapInjectsAndRedirects(mapping); } } diff --git a/src/main/java/com/replaymod/gradle/remap/PsiUtils.java b/src/main/java/com/replaymod/gradle/remap/PsiUtils.java new file mode 100644 index 0000000..ec4d1c8 --- /dev/null +++ b/src/main/java/com/replaymod/gradle/remap/PsiUtils.java @@ -0,0 +1,61 @@ +package com.replaymod.gradle.remap; + +import com.intellij.psi.PsiArrayType; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiClassType; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiPrimitiveType; +import com.intellij.psi.PsiType; +import com.intellij.psi.util.TypeConversionUtil; +import org.cadixdev.bombe.type.ArrayType; +import org.cadixdev.bombe.type.FieldType; +import org.cadixdev.bombe.type.MethodDescriptor; +import org.cadixdev.bombe.type.ObjectType; +import org.cadixdev.bombe.type.Type; +import org.cadixdev.bombe.type.VoidType; +import org.cadixdev.bombe.type.signature.MethodSignature; + +import java.util.Arrays; +import java.util.stream.Collectors; + +class PsiUtils { + static MethodSignature getSignature(PsiMethod method) { + return new MethodSignature(method.getName(), getDescriptor(method)); + } + + private static MethodDescriptor getDescriptor(PsiMethod method) { + return new MethodDescriptor( + Arrays.stream(method.getParameterList().getParameters()) + .map(it -> getFieldType(it.getType())) + .collect(Collectors.toList()), + getType(method.getReturnType()) + ); + } + + private static FieldType getFieldType(PsiType type) { + type = TypeConversionUtil.erasure(type); + if (type instanceof PsiPrimitiveType) { + return FieldType.of(((PsiPrimitiveType) type).getKind().getBinaryName()); + } else if (type instanceof PsiArrayType) { + PsiArrayType array = (PsiArrayType) type; + return new ArrayType(array.getArrayDimensions(), getFieldType(array.getDeepComponentType())); + } else if (type instanceof PsiClassType) { + PsiClass resolved = ((PsiClassType) type).resolve(); + if (resolved == null) throw new NullPointerException("Failed to resolve type " + type); + String qualifiedName = resolved.getQualifiedName(); + if (qualifiedName == null) throw new NullPointerException("Type " + type + " has no qualified name."); + return new ObjectType(qualifiedName); + } else { + throw new IllegalArgumentException("Cannot translate type " + type); + } + } + + private static Type getType(PsiType type) { + if (TypeConversionUtil.isVoidType(type)) { + return VoidType.INSTANCE; + } else { + return getFieldType(type); + } + } + +} diff --git a/src/main/java/com/replaymod/gradle/remap/Transformer.java b/src/main/java/com/replaymod/gradle/remap/Transformer.java index 1cbd425..8a9ec9c 100644 --- a/src/main/java/com/replaymod/gradle/remap/Transformer.java +++ b/src/main/java/com/replaymod/gradle/remap/Transformer.java @@ -11,6 +11,8 @@ import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.openapi.vfs.local.CoreLocalFileSystem; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; +import com.replaymod.gradle.remap.legacy.LegacyMapping; +import org.cadixdev.lorenz.MappingSet; import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys; import org.jetbrains.kotlin.cli.common.config.KotlinSourceRoot; import org.jetbrains.kotlin.cli.common.messages.MessageRenderer; @@ -37,21 +39,20 @@ import java.util.Comparator; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; -import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; class Transformer { - private Map<String, Mapping> map; + private MappingSet map; private String[] classpath; private boolean fail; public static void main(String[] args) throws IOException { - Map<String, Mapping> mappings; + MappingSet mappings; if (args[0].isEmpty()) { - mappings = new HashMap<>(); + mappings = MappingSet.create(); } else { - mappings = readMappings(new File(args[0]), args[1].equals("true")); + mappings = LegacyMapping.readMappingSet(new File(args[0]).toPath(), args[1].equals("true")); } Transformer transformer = new Transformer(mappings); @@ -95,7 +96,7 @@ class Transformer { } } - public Transformer(Map<String, Mapping> mappings) { + public Transformer(MappingSet mappings) { this.map = mappings; } @@ -165,104 +166,4 @@ class Transformer { } } - public static class Mapping { - public String oldName; - public String newName; - public Map<String, String> fields = new HashMap<>(); - public Map<String, String> methods = new HashMap<>(); - } - - public static Map<String, Mapping> readMappings(File mappingFile, boolean invert) throws IOException { - Map<String, Mapping> mappings = new HashMap<>(); - Map<String, Mapping> revMappings = new HashMap<>(); - int lineNumber = 0; - for (String line : Files.readAllLines(mappingFile.toPath(), StandardCharsets.UTF_8)) { - lineNumber++; - if (line.trim().startsWith("#") || line.trim().isEmpty()) continue; - - String[] parts = line.split(" "); - if (parts.length < 2 || line.contains(";")) { - throw new IllegalArgumentException("Failed to parse line " + lineNumber + " in " + mappingFile.getPath() + "."); - } - - Mapping mapping = mappings.get(parts[0]); - if (mapping == null) { - mapping = new Mapping(); - mapping.oldName = mapping.newName = parts[0]; - mappings.put(mapping.oldName, mapping); - } - - if (parts.length == 2) { - // Class mapping - mapping.newName = parts[1]; - // Possibly merge with reverse mapping - Mapping revMapping = revMappings.remove(mapping.newName); - if (revMapping != null) { - mapping.fields.putAll(revMapping.fields); - mapping.methods.putAll(revMapping.methods); - } - revMappings.put(mapping.newName, mapping); - } else if (parts.length == 3 || parts.length == 4) { - String fromName = parts[1]; - String toName; - Mapping revMapping; - if (parts.length == 4) { - toName = parts[3]; - revMapping = revMappings.get(parts[2]); - if (revMapping == null) { - revMapping = new Mapping(); - revMapping.oldName = revMapping.newName = parts[2]; - revMappings.put(revMapping.newName, revMapping); - } - } else { - toName = parts[2]; - revMapping = mapping; - } - if (fromName.endsWith("()")) { - // Method mapping - fromName = fromName.substring(0, fromName.length() - 2); - toName = toName.substring(0, toName.length() - 2); - mapping.methods.put(fromName, toName); - revMapping.methods.put(fromName, toName); - } else { - // Field mapping - mapping.fields.put(fromName, toName); - revMapping.fields.put(fromName, toName); - } - } else { - throw new IllegalArgumentException("Failed to parse line " + lineNumber + " in " + mappingFile.getPath() + "."); - } - } - if (invert) { - Stream.concat( - mappings.values().stream(), - revMappings.values().stream() - ).distinct().forEach(it -> { - String oldName = it.oldName; - it.oldName = it.newName; - it.newName = oldName; - it.fields = it.fields.entrySet().stream().collect(Collectors.toMap(Entry::getValue, Entry::getKey)); - it.methods = it.methods.entrySet().stream().collect(Collectors.toMap(Entry::getValue, Entry::getKey)); - }); - } - return Stream.concat( - mappings.values().stream(), - revMappings.values().stream() - ).collect(Collectors.toMap(mapping -> mapping.oldName, Function.identity(), (mapping, other) -> { - if (!other.oldName.equals(other.newName)) { - if (!mapping.oldName.equals(mapping.newName) - && !other.oldName.equals(mapping.oldName) - && !other.newName.equals(mapping.newName)) { - throw new IllegalArgumentException("Conflicting mappings: " - + mapping.oldName + " -> " + mapping.newName - + " and " + other.oldName + " -> " + other.newName); - } - mapping.oldName = other.oldName; - mapping.newName = other.newName; - } - mapping.fields.putAll(other.fields); - mapping.methods.putAll(other.methods); - return mapping; - })); - } } diff --git a/src/main/java/com/replaymod/gradle/remap/legacy/LegacyMapping.java b/src/main/java/com/replaymod/gradle/remap/legacy/LegacyMapping.java new file mode 100644 index 0000000..05a85d9 --- /dev/null +++ b/src/main/java/com/replaymod/gradle/remap/legacy/LegacyMapping.java @@ -0,0 +1,118 @@ +package com.replaymod.gradle.remap.legacy; + +import org.cadixdev.lorenz.MappingSet; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class LegacyMapping { + public static MappingSet readMappingSet(Path mappingFile, boolean invert) throws IOException { + return new LegacyMappingsReader(readMappings(mappingFile, invert)).read(); + } + + public static Map<String, LegacyMapping> readMappings(Path mappingFile, boolean invert) throws IOException { + Map<String, LegacyMapping> mappings = new HashMap<>(); + Map<String, LegacyMapping> revMappings = new HashMap<>(); + int lineNumber = 0; + for (String line : Files.readAllLines(mappingFile, StandardCharsets.UTF_8)) { + lineNumber++; + if (line.trim().startsWith("#") || line.trim().isEmpty()) continue; + + String[] parts = line.split(" "); + if (parts.length < 2 || line.contains(";")) { + throw new IllegalArgumentException("Failed to parse line " + lineNumber + " in " + mappingFile + "."); + } + + LegacyMapping mapping = mappings.get(parts[0]); + if (mapping == null) { + mapping = new LegacyMapping(); + mapping.oldName = mapping.newName = parts[0]; + mappings.put(mapping.oldName, mapping); + } + + if (parts.length == 2) { + // Class mapping + mapping.newName = parts[1]; + // Possibly merge with reverse mapping + LegacyMapping revMapping = revMappings.remove(mapping.newName); + if (revMapping != null) { + mapping.fields.putAll(revMapping.fields); + mapping.methods.putAll(revMapping.methods); + } + revMappings.put(mapping.newName, mapping); + } else if (parts.length == 3 || parts.length == 4) { + String fromName = parts[1]; + String toName; + LegacyMapping revMapping; + if (parts.length == 4) { + toName = parts[3]; + revMapping = revMappings.get(parts[2]); + if (revMapping == null) { + revMapping = new LegacyMapping(); + revMapping.oldName = revMapping.newName = parts[2]; + revMappings.put(revMapping.newName, revMapping); + } + } else { + toName = parts[2]; + revMapping = mapping; + } + if (fromName.endsWith("()")) { + // Method mapping + fromName = fromName.substring(0, fromName.length() - 2); + toName = toName.substring(0, toName.length() - 2); + mapping.methods.put(fromName, toName); + revMapping.methods.put(fromName, toName); + } else { + // Field mapping + mapping.fields.put(fromName, toName); + revMapping.fields.put(fromName, toName); + } + } else { + throw new IllegalArgumentException("Failed to parse line " + lineNumber + " in " + mappingFile + "."); + } + } + if (invert) { + Stream.concat( + mappings.values().stream(), + revMappings.values().stream() + ).distinct().forEach(it -> { + String oldName = it.oldName; + it.oldName = it.newName; + it.newName = oldName; + it.fields = it.fields.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey)); + it.methods = it.methods.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey)); + }); + } + return Stream.concat( + mappings.values().stream(), + revMappings.values().stream() + ).collect(Collectors.toMap(mapping -> mapping.oldName, Function.identity(), (mapping, other) -> { + if (!other.oldName.equals(other.newName)) { + if (!mapping.oldName.equals(mapping.newName) + && !other.oldName.equals(mapping.oldName) + && !other.newName.equals(mapping.newName)) { + throw new IllegalArgumentException("Conflicting mappings: " + + mapping.oldName + " -> " + mapping.newName + + " and " + other.oldName + " -> " + other.newName); + } + mapping.oldName = other.oldName; + mapping.newName = other.newName; + } + mapping.fields.putAll(other.fields); + mapping.methods.putAll(other.methods); + return mapping; + })); + } + + public String oldName; + public String newName; + public Map<String, String> fields = new HashMap<>(); + public Map<String, String> methods = new HashMap<>(); +} diff --git a/src/main/java/com/replaymod/gradle/remap/legacy/LegacyMappingSetModelFactory.java b/src/main/java/com/replaymod/gradle/remap/legacy/LegacyMappingSetModelFactory.java new file mode 100644 index 0000000..eb72788 --- /dev/null +++ b/src/main/java/com/replaymod/gradle/remap/legacy/LegacyMappingSetModelFactory.java @@ -0,0 +1,36 @@ +package com.replaymod.gradle.remap.legacy; + +import org.cadixdev.bombe.type.signature.MethodSignature; +import org.cadixdev.lorenz.MappingSet; +import org.cadixdev.lorenz.impl.MappingSetModelFactoryImpl; +import org.cadixdev.lorenz.impl.model.TopLevelClassMappingImpl; +import org.cadixdev.lorenz.model.MethodMapping; +import org.cadixdev.lorenz.model.TopLevelClassMapping; + +import java.util.Optional; + +public class LegacyMappingSetModelFactory extends MappingSetModelFactoryImpl { + @Override + public TopLevelClassMapping createTopLevelClassMapping(MappingSet parent, String obfuscatedName, String deobfuscatedName) { + return new TopLevelClassMappingImpl(parent, obfuscatedName, deobfuscatedName) { + private MethodSignature stripDesc(MethodSignature signature) { + // actual descriptor isn't included in legacy format + return MethodSignature.of(signature.getName(), "()V"); + } + + @Override + public boolean hasMethodMapping(MethodSignature signature) { + return super.hasMethodMapping(signature) || super.hasMethodMapping(stripDesc(signature)); + } + + @Override + public Optional<MethodMapping> getMethodMapping(MethodSignature signature) { + Optional<MethodMapping> maybeMapping = super.getMethodMapping(signature); + if (!maybeMapping.isPresent() || !maybeMapping.get().hasMappings()) { + maybeMapping = super.getMethodMapping(stripDesc(signature)); + } + return maybeMapping; + } + }; + } +} diff --git a/src/main/java/com/replaymod/gradle/remap/legacy/LegacyMappingsReader.java b/src/main/java/com/replaymod/gradle/remap/legacy/LegacyMappingsReader.java new file mode 100644 index 0000000..502f7ba --- /dev/null +++ b/src/main/java/com/replaymod/gradle/remap/legacy/LegacyMappingsReader.java @@ -0,0 +1,44 @@ +package com.replaymod.gradle.remap.legacy; + +import org.cadixdev.lorenz.MappingSet; +import org.cadixdev.lorenz.io.MappingsReader; +import org.cadixdev.lorenz.model.ClassMapping; + +import java.util.Map; + +public class LegacyMappingsReader extends MappingsReader { + private final Map<String, LegacyMapping> map; + + public LegacyMappingsReader(Map<String, LegacyMapping> map) { + this.map = map; + } + + @Override + public MappingSet read() { + return read(MappingSet.create(new LegacyMappingSetModelFactory())); + } + + @Override + public MappingSet read(MappingSet mappings) { + if (!(mappings.getModelFactory() instanceof LegacyMappingSetModelFactory)) { + throw new IllegalArgumentException("legacy mappings must use legacy model factory, use read() instead"); + } + for (LegacyMapping legacyMapping : map.values()) { + ClassMapping classMapping = mappings.getOrCreateClassMapping(legacyMapping.oldName) + .setDeobfuscatedName(legacyMapping.newName); + for (Map.Entry<String, String> entry : legacyMapping.fields.entrySet()) { + classMapping.getOrCreateFieldMapping(entry.getKey()) + .setDeobfuscatedName(entry.getValue()); + } + for (Map.Entry<String, String> entry : legacyMapping.methods.entrySet()) { + classMapping.getOrCreateMethodMapping(entry.getKey(), "()V") + .setDeobfuscatedName(entry.getValue()); + } + } + return mappings; + } + + @Override + public void close() { + } +} |