From 00fcd0550fcdda621c2e4662f6ddd55ce673b931 Mon Sep 17 00:00:00 2001
From: Gegy
Date: Thu, 24 Jan 2019 14:48:32 +0200
Subject: [WIP] Mapping rework (#91)
* Move packages
* Mapping & entry refactor: first pass
* Fix deobf -> obf tree remapping
* Resolve various issues
* Give all entries the potential for parents and treat inner classes as children
* Deobf UI tree elements
* Tests pass
* Sort mapping output
* Fix delta tracking
* Index separation and first pass for #97
* Keep track of remapped jar index
* Fix child entries not being remapped
* Drop non-root entries
* Track dropped mappings
* Fix enigma mapping ordering
* EntryTreeNode interface
* Small tweaks
* Naive full index remap on rename
* Entries can resolve to more than one root entry
* Support alternative resolution strategies
* Bridge method resolution
* Tests pass
* Fix mappings being used where there are none
* Fix methods with different descriptors being considered unique. closes #89
---
src/main/java/cuchaz/enigma/mapping/Mappings.java | 268 ----------------------
1 file changed, 268 deletions(-)
delete mode 100644 src/main/java/cuchaz/enigma/mapping/Mappings.java
(limited to 'src/main/java/cuchaz/enigma/mapping/Mappings.java')
diff --git a/src/main/java/cuchaz/enigma/mapping/Mappings.java b/src/main/java/cuchaz/enigma/mapping/Mappings.java
deleted file mode 100644
index c865079..0000000
--- a/src/main/java/cuchaz/enigma/mapping/Mappings.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2015 Jeff Martin.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the GNU Lesser General Public
- * License v3.0 which accompanies this distribution, and is available at
- * http://www.gnu.org/licenses/lgpl.html
- *
- * Contributors:
- * Jeff Martin - initial API and implementation
- ******************************************************************************/
-
-package cuchaz.enigma.mapping;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import cuchaz.enigma.analysis.TranslationIndex;
-import cuchaz.enigma.api.EnigmaPlugin;
-import cuchaz.enigma.bytecode.AccessFlags;
-import cuchaz.enigma.mapping.entry.ClassEntry;
-import cuchaz.enigma.mapping.entry.MethodEntry;
-import cuchaz.enigma.throwables.MappingConflict;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.*;
-import java.util.stream.Collectors;
-
-public class Mappings {
-
- private final FormatType originMapping;
- protected Map classesByObf;
- protected Map classesByDeobf;
- private Mappings previousState;
-
- public Mappings() {
- this(FormatType.ENIGMA_DIRECTORY);
- }
-
- public Mappings(FormatType originMapping) {
- this.originMapping = originMapping;
- this.classesByObf = Maps.newHashMap();
- this.classesByDeobf = Maps.newHashMap();
- }
-
- public Collection classes() {
- assert (this.classesByObf.size() >= this.classesByDeobf.size());
- return this.classesByObf.values();
- }
-
- public void addClassMapping(ClassMapping classMapping) throws MappingConflict {
- if (this.classesByObf.containsKey(classMapping.getObfFullName())) {
- throw new MappingConflict("class", classMapping.getObfFullName(), this.classesByObf.get(classMapping.getObfFullName()).getObfFullName());
- }
- this.classesByObf.put(classMapping.getObfFullName(), classMapping);
-
- if (classMapping.getDeobfName() != null) {
- if (this.classesByDeobf.containsKey(classMapping.getDeobfName())) {
- throw new MappingConflict("class", classMapping.getDeobfName(), this.classesByDeobf.get(classMapping.getDeobfName()).getDeobfName());
- }
- this.classesByDeobf.put(classMapping.getDeobfName(), classMapping);
- }
- }
-
- public void removeClassMapping(ClassMapping classMapping) {
- boolean obfWasRemoved = this.classesByObf.remove(classMapping.getObfFullName()) != null;
- assert (obfWasRemoved);
- if (classMapping.getDeobfName() != null) {
- boolean deobfWasRemoved = this.classesByDeobf.remove(classMapping.getDeobfName()) != null;
- assert (deobfWasRemoved);
- }
- }
-
- public ClassMapping getClassByObf(ClassEntry entry) {
- return getClassByObf(entry.getName());
- }
-
- public ClassMapping getClassByObf(String obfName) {
- return this.classesByObf.get(obfName);
- }
-
- public ClassMapping getClassByDeobf(ClassEntry entry) {
- return getClassByDeobf(entry.getName());
- }
-
- public ClassMapping getClassByDeobf(String deobfName) {
- return this.classesByDeobf.get(deobfName);
- }
-
- public void setClassDeobfName(ClassMapping classMapping, String deobfName) {
- if (classMapping.getDeobfName() != null) {
- boolean wasRemoved = this.classesByDeobf.remove(classMapping.getDeobfName()) != null;
- assert (wasRemoved);
- }
- classMapping.setDeobfName(deobfName);
- if (deobfName != null) {
- boolean wasAdded = this.classesByDeobf.put(deobfName, classMapping) == null;
- assert (wasAdded);
- }
- }
-
- public Translator getTranslator(TranslationDirection direction, TranslationIndex index) {
- switch (direction) {
- case DEOBFUSCATING:
-
- return new DirectionalTranslator(direction, this.classesByObf, index);
-
- case OBFUSCATING:
-
- // fill in the missing deobf class entries with obf entries
- Map classes = Maps.newHashMap();
- for (ClassMapping classMapping : classes()) {
- if (classMapping.getDeobfName() != null) {
- classes.put(classMapping.getDeobfName(), classMapping);
- } else {
- classes.put(classMapping.getObfFullName(), classMapping);
- }
- }
-
- // translate the translation index
- // NOTE: this isn't actually recursive
- TranslationIndex deobfIndex = new TranslationIndex(index, getTranslator(TranslationDirection.DEOBFUSCATING, index));
-
- return new DirectionalTranslator(direction, classes, deobfIndex);
-
- default:
- throw new Error("Invalid translation direction!");
- }
- }
-
- @Override
- public String toString() {
- StringBuilder buf = new StringBuilder();
- for (ClassMapping classMapping : this.classesByObf.values()) {
- buf.append(classMapping);
- buf.append("\n");
- }
- return buf.toString();
- }
-
- public void renameObfClass(String oldObfName, String newObfName) {
- new ArrayList<>(classes()).stream().filter(classMapping -> classMapping.renameObfClass(oldObfName, newObfName)).forEach(classMapping -> {
- boolean wasRemoved = this.classesByObf.remove(oldObfName) != null;
- assert (wasRemoved);
- boolean wasAdded = this.classesByObf.put(newObfName, classMapping) == null;
- assert (wasAdded);
- });
- }
-
- public Set getAllObfClassNames() {
- final Set classNames = Sets.newHashSet();
- for (ClassMapping classMapping : classes()) {
-
- // add the class name
- classNames.add(classMapping.getObfFullName());
-
- // add classes from method signatures
- for (MethodMapping methodMapping : classMapping.methods()) {
- for (TypeDescriptor desc : methodMapping.getObfDesc().types()) {
- if (desc.containsType()) {
- classNames.add(desc.getTypeEntry().getClassName());
- }
- }
- }
- }
- return classNames;
- }
-
- public boolean containsDeobfClass(String deobfName) {
- return this.classesByDeobf.containsKey(deobfName);
- }
-
- public boolean containsDeobfField(ClassEntry obfClassEntry, String deobfName, TypeDescriptor obfDesc) {
- ClassMapping classMapping = this.classesByObf.get(obfClassEntry.getName());
- return classMapping != null && classMapping.containsDeobfField(deobfName, obfDesc);
- }
-
- public boolean containsDeobfField(ClassEntry obfClassEntry, String deobfName) {
- ClassMapping classMapping = this.classesByObf.get(obfClassEntry.getName());
- if (classMapping != null)
- for (FieldMapping fieldMapping : classMapping.fields())
- if (deobfName.equals(fieldMapping.getDeobfName()) || deobfName.equals(fieldMapping.getObfName()))
- return true;
-
- return false;
- }
-
- public boolean containsDeobfMethod(ClassEntry obfClassEntry, String deobfName, MethodDescriptor obfDescriptor) {
- ClassMapping classMapping = this.classesByObf.get(obfClassEntry.getName());
- return classMapping != null && classMapping.containsDeobfMethod(deobfName, obfDescriptor);
- }
-
- public boolean containsArgument(MethodEntry obfMethodEntry, String name) {
- ClassMapping classMapping = this.classesByObf.get(obfMethodEntry.getClassName());
- return classMapping != null && classMapping.containsArgument(obfMethodEntry, name);
- }
-
- public List getClassMappingChain(ClassEntry obfClass) {
- List mappingChain = Lists.newArrayList();
- ClassMapping classMapping = null;
- for (ClassEntry obfClassEntry : obfClass.getClassChain()) {
- if (mappingChain.isEmpty()) {
- classMapping = this.classesByObf.get(obfClassEntry.getName());
- } else if (classMapping != null) {
- classMapping = classMapping.getInnerClassByObfSimple(obfClassEntry.getInnermostClassName());
- }
- mappingChain.add(classMapping);
- }
- return mappingChain;
- }
-
- public FormatType getOriginMappingFormat() {
- return originMapping;
- }
-
- public void savePreviousState() {
- this.previousState = new Mappings(this.originMapping);
- this.previousState.classesByDeobf = new HashMap<>();
- for (Map.Entry entry : this.classesByDeobf.entrySet()) {
- this.previousState.classesByDeobf.put(entry.getKey(), entry.getValue().copy());
- }
- this.previousState.classesByObf = new HashMap<>();
- for (Map.Entry entry : this.classesByObf.entrySet()) {
- this.previousState.classesByObf.put(entry.getKey(), entry.getValue().copy());
- }
- classesByDeobf.values().forEach(ClassMapping::resetDirty);
- classesByObf.values().forEach(ClassMapping::resetDirty);
- }
-
- public void saveEnigmaMappings(File file, boolean isDirectoryFormat) throws IOException {
- new MappingsEnigmaWriter().write(file, this, isDirectoryFormat);
- this.savePreviousState();
- }
-
- public void saveSRGMappings(File file) throws IOException {
- new MappingsSRGWriter().write(file, this);
- }
-
- public Mappings getPreviousState() {
- return previousState;
- }
-
- public enum FormatType {
- ENIGMA_FILE, ENIGMA_DIRECTORY, TINY_FILE, SRG_FILE
- }
-
- public enum EntryModifier {
- UNCHANGED, PUBLIC, PROTECTED, PRIVATE;
-
- public String getFormattedName() {
- return " ACC:" + super.toString();
- }
-
- public AccessFlags transform(AccessFlags access) {
- switch (this) {
- case PUBLIC:
- return access.setPublic();
- case PROTECTED:
- return access.setProtected();
- case PRIVATE:
- return access.setPrivate();
- case UNCHANGED:
- default:
- return access;
- }
- }
- }
-}
--
cgit v1.2.3