From 1ec1ece9efbcc668b9c79de58d79b3176da1b7ca Mon Sep 17 00:00:00 2001 From: YanisBft Date: Tue, 15 Jun 2021 23:30:03 +0200 Subject: Structure panel options (#400) * Structure panel options * changes * always show inner classes in the tree * workaround for toString() and similar * show constructor methods depending on the class obfuscation * use ListCellRenderer instead of toString * list cell renderer--- .../cuchaz/enigma/analysis/StructureTreeNode.java | 54 ++++++++++++++------ .../enigma/analysis/StructureTreeOptions.java | 59 ++++++++++++++++++++++ 2 files changed, 98 insertions(+), 15 deletions(-) create mode 100644 enigma/src/main/java/cuchaz/enigma/analysis/StructureTreeOptions.java (limited to 'enigma/src/main/java') diff --git a/enigma/src/main/java/cuchaz/enigma/analysis/StructureTreeNode.java b/enigma/src/main/java/cuchaz/enigma/analysis/StructureTreeNode.java index b4343c1..aea7618 100644 --- a/enigma/src/main/java/cuchaz/enigma/analysis/StructureTreeNode.java +++ b/enigma/src/main/java/cuchaz/enigma/analysis/StructureTreeNode.java @@ -10,7 +10,9 @@ import cuchaz.enigma.translation.representation.entry.*; import javax.swing.tree.DefaultMutableTreeNode; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; +import java.util.stream.Stream; public class StructureTreeNode extends DefaultMutableTreeNode { private final List nameProposalServices; @@ -32,25 +34,47 @@ public class StructureTreeNode extends DefaultMutableTreeNode { return this.entry; } - public void load(EnigmaProject project, boolean hideDeobfuscated) { - List children = project.getJarIndex().getChildrenByClass().get(this.parentEntry); - - for (ParentedEntry child : children) { + public void load(EnigmaProject project, StructureTreeOptions options) { + Stream children = project.getJarIndex().getChildrenByClass().get(this.parentEntry).stream(); + + children = switch (options.obfuscationVisibility()) { + case ALL -> children; + case OBFUSCATED -> children + // remove deobfuscated members if only obfuscated, unless it's an inner class + .filter(e -> (e instanceof ClassEntry) || (project.isObfuscated(e) && project.isRenamable(e))) + // keep constructor methods if the class is obfuscated + .filter(e -> !(e instanceof MethodEntry m && m.isConstructor()) || project.isObfuscated(e.getParent())); + case DEOBFUSCATED -> children.filter(e -> (e instanceof ClassEntry) + || (!project.isObfuscated(e) && project.isRenamable(e)) + // keep constructor methods if the class is deobfuscated + || (e instanceof MethodEntry m && m.isConstructor()) && !project.isObfuscated(e.getParent())); + }; + + children = switch (options.documentationVisibility()) { + case ALL -> children; + // TODO remove EntryRemapper.deobfuscate() calls when javadocs will no longer be tied to deobfuscation + case DOCUMENTED -> children.filter(e -> (e instanceof ClassEntry) || (project.getMapper().deobfuscate(e).getJavadocs() != null && !project.getMapper().deobfuscate(e).getJavadocs().isBlank())); + case NON_DOCUMENTED -> children.filter(e -> (e instanceof ClassEntry) || (project.getMapper().deobfuscate(e).getJavadocs() == null || project.getMapper().deobfuscate(e).getJavadocs().isBlank())); + }; + + children = switch (options.sortingOrder()) { + case DEFAULT -> children; + case A_Z -> children.sorted(Comparator.comparing(e -> (e instanceof MethodEntry m && m.isConstructor()) + // compare the class name when the entry is a constructor + ? project.getMapper().deobfuscate(e.getParent()).getSimpleName().toLowerCase() + : project.getMapper().deobfuscate(e).getSimpleName().toLowerCase())); + case Z_A -> children.sorted(Comparator.comparing(e -> (e instanceof MethodEntry m && m.isConstructor()) + ? project.getMapper().deobfuscate(((ParentedEntry) e).getParent()).getSimpleName().toLowerCase() + : project.getMapper().deobfuscate((ParentedEntry) e).getSimpleName().toLowerCase()) + .reversed()); + }; + + for (ParentedEntry child : children.toList()) { StructureTreeNode childNode = new StructureTreeNode(project, this.parentEntry, child); if (child instanceof ClassEntry) { childNode = new StructureTreeNode(project, (ClassEntry) child, child); - childNode.load(project, hideDeobfuscated); - } - - // don't add deobfuscated members if hideDeobfuscated is true, unless it's an inner class - if (hideDeobfuscated && !project.isObfuscated(child) && !(child instanceof ClassEntry)) { - continue; - } - - // don't add constructor methods if hideDeobfuscated is true - if (hideDeobfuscated && (child instanceof MethodEntry method) && method.isConstructor()) { - continue; + childNode.load(project, options); } this.add(childNode); diff --git a/enigma/src/main/java/cuchaz/enigma/analysis/StructureTreeOptions.java b/enigma/src/main/java/cuchaz/enigma/analysis/StructureTreeOptions.java new file mode 100644 index 0000000..cfc80b4 --- /dev/null +++ b/enigma/src/main/java/cuchaz/enigma/analysis/StructureTreeOptions.java @@ -0,0 +1,59 @@ +package cuchaz.enigma.analysis; + +public record StructureTreeOptions( + ObfuscationVisibility obfuscationVisibility, + DocumentationVisibility documentationVisibility, + SortingOrder sortingOrder) { + + public enum ObfuscationVisibility implements Option { + ALL("structure.options.obfuscation.all"), + OBFUSCATED("structure.options.obfuscation.obfuscated"), + DEOBFUSCATED("structure.options.obfuscation.deobfuscated"); + + private final String translationKey; + + ObfuscationVisibility(String translationKey) { + this.translationKey = translationKey; + } + + public String getTranslationKey() { + return this.translationKey; + } + } + + public enum DocumentationVisibility implements Option { + ALL("structure.options.documentation.all"), + DOCUMENTED("structure.options.documentation.documented"), + NON_DOCUMENTED("structure.options.documentation.non_documented"); + + private final String translationKey; + + DocumentationVisibility(String translationKey) { + this.translationKey = translationKey; + } + + public String getTranslationKey() { + return this.translationKey; + } + } + + public enum SortingOrder implements Option { + DEFAULT("structure.options.sorting.default"), + A_Z("structure.options.sorting.a_z"), + Z_A("structure.options.sorting.z_a"); + + private final String translationKey; + + SortingOrder(String translationKey) { + this.translationKey = translationKey; + } + + public String getTranslationKey() { + return this.translationKey; + } + } + + public interface Option { + String getTranslationKey(); + } +} -- cgit v1.2.3