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 --- .../cuchaz/enigma/analysis/IndexTreeBuilder.java | 87 ++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 src/main/java/cuchaz/enigma/analysis/IndexTreeBuilder.java (limited to 'src/main/java/cuchaz/enigma/analysis/IndexTreeBuilder.java') diff --git a/src/main/java/cuchaz/enigma/analysis/IndexTreeBuilder.java b/src/main/java/cuchaz/enigma/analysis/IndexTreeBuilder.java new file mode 100644 index 0000000..4ca7cd1 --- /dev/null +++ b/src/main/java/cuchaz/enigma/analysis/IndexTreeBuilder.java @@ -0,0 +1,87 @@ +package cuchaz.enigma.analysis; + +import com.google.common.collect.Lists; +import cuchaz.enigma.analysis.index.EntryIndex; +import cuchaz.enigma.analysis.index.JarIndex; +import cuchaz.enigma.translation.Translator; +import cuchaz.enigma.translation.mapping.ResolutionStrategy; +import cuchaz.enigma.translation.representation.entry.ClassEntry; +import cuchaz.enigma.translation.representation.entry.MethodEntry; + +import java.util.List; + +public class IndexTreeBuilder { + private final JarIndex index; + + public IndexTreeBuilder(JarIndex index) { + this.index = index; + } + + public ClassInheritanceTreeNode buildClassInheritance(Translator translator, ClassEntry obfClassEntry) { + // get the root node + List ancestry = Lists.newArrayList(); + ancestry.add(obfClassEntry.getFullName()); + for (ClassEntry classEntry : index.getInheritanceIndex().getAncestors(obfClassEntry)) { + ancestry.add(classEntry.getFullName()); + } + + ClassInheritanceTreeNode rootNode = new ClassInheritanceTreeNode(translator, ancestry.get(ancestry.size() - 1)); + + // expand all children recursively + rootNode.load(index.getInheritanceIndex(), true); + + return rootNode; + } + + public ClassImplementationsTreeNode buildClassImplementations(Translator translator, ClassEntry obfClassEntry) { + if (index.getInheritanceIndex().isParent(obfClassEntry)) { + ClassImplementationsTreeNode node = new ClassImplementationsTreeNode(translator, obfClassEntry); + node.load(index); + return node; + } + return null; + } + + public MethodInheritanceTreeNode buildMethodInheritance(Translator translator, MethodEntry obfMethodEntry) { + MethodEntry resolvedEntry = index.getEntryResolver().resolveFirstEntry(obfMethodEntry, ResolutionStrategy.RESOLVE_ROOT); + + // make a root node at the base + MethodInheritanceTreeNode rootNode = new MethodInheritanceTreeNode( + translator, resolvedEntry, + index.getEntryIndex().hasMethod(resolvedEntry) + ); + + // expand the full tree + rootNode.load(index, true); + + return rootNode; + } + + public List buildMethodImplementations(Translator translator, MethodEntry obfMethodEntry) { + EntryIndex entryIndex = index.getEntryIndex(); + + List ancestorMethodEntries = Lists.newArrayList(); + + if (entryIndex.hasMethod(obfMethodEntry)) { + ancestorMethodEntries.add(obfMethodEntry); + } + + for (ClassEntry ancestorEntry : index.getInheritanceIndex().getAncestors(obfMethodEntry.getParent())) { + MethodEntry ancestorMethod = obfMethodEntry.withParent(ancestorEntry); + if (entryIndex.hasMethod(ancestorMethod)) { + ancestorMethodEntries.add(ancestorMethod); + } + } + + List nodes = Lists.newArrayList(); + if (!ancestorMethodEntries.isEmpty()) { + for (MethodEntry interfaceMethodEntry : ancestorMethodEntries) { + MethodImplementationsTreeNode node = new MethodImplementationsTreeNode(translator, interfaceMethodEntry); + node.load(index); + nodes.add(node); + } + } + + return nodes; + } +} -- cgit v1.2.3