From f992016433d44c2d16244035bd9131ba79e1c8a4 Mon Sep 17 00:00:00 2001 From: Eli Orona Date: Thu, 9 Dec 2021 11:20:20 -0800 Subject: [PATCH 1/5] Allow filtering of packages in Mapping Stats window --- .../cuchaz/enigma/gui/dialog/StatsDialog.java | 30 ++++++++++++---- .../enigma/gui/stats/StatsGenerator.java | 36 ++++++++++++++++--- enigma/src/main/resources/lang/en_us.json | 2 ++ 3 files changed, 57 insertions(+), 11 deletions(-) diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/StatsDialog.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/StatsDialog.java index 1ab66ef2d..b39b95357 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/StatsDialog.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/StatsDialog.java @@ -36,14 +36,13 @@ public static void show(Gui gui) { for (StatsMember member : StatsMember.values()) { results.put(member, statsGenerator.generate(listener, Collections.singleton(member), "", false)); } - - SwingUtilities.invokeLater(() -> show(gui, results)); + SwingUtilities.invokeLater(() -> show(gui, results, "")); }); } - public static void show(Gui gui, Map results) { + public static void show(Gui gui, Map results, String packageName) { // init frame - JDialog dialog = new JDialog(gui.getFrame(), I18n.translate("menu.file.stats.title"), true); + JDialog dialog = new JDialog(gui.getFrame(), packageName.isEmpty() ? I18n.translate("menu.file.stats.title") : I18n.translateFormatted("menu.file.stats.title_filtered", packageName), true); Container contentPane = dialog.getContentPane(); contentPane.setLayout(new GridBagLayout()); @@ -80,10 +79,29 @@ public static void show(Gui gui, Map results) { topLevelPackage.setText(UiConfig.getLastTopLevelPackage()); contentPane.add(topLevelPackage, cb1.pos(0, results.size() + 2).fill(GridBagConstraints.HORIZONTAL).build()); + // Show filter button + JButton filterButton = new JButton(I18n.translate("menu.file.stats.filter")); + filterButton.addActionListener(action -> { + dialog.dispose(); + ProgressDialog.runOffThread(gui.getFrame(), listener -> { + UiConfig.setLastTopLevelPackage(topLevelPackage.getText()); + UiConfig.save(); + + final StatsGenerator statsGenerator = new StatsGenerator(gui.getController().project); + final Map _results = new HashMap<>(); + for (StatsMember member : StatsMember.values()) { + _results.put(member, statsGenerator.generate(listener, Collections.singleton(member), UiConfig.getLastTopLevelPackage(), false)); + } + SwingUtilities.invokeLater(() -> show(gui, _results, UiConfig.getLastTopLevelPackage())); + }); + + }); + contentPane.add(filterButton, cb1.pos(0, results.size() + 3).anchor(GridBagConstraints.EAST).build()); + // show synthetic members option JCheckBox syntheticParametersOption = new JCheckBox(I18n.translate("menu.file.stats.synthetic_parameters")); syntheticParametersOption.setSelected(UiConfig.shouldIncludeSyntheticParameters()); - contentPane.add(syntheticParametersOption, cb1.pos(0, results.size() + 3).build()); + contentPane.add(syntheticParametersOption, cb1.pos(0, results.size() + 4).build()); // show generate button JButton button = new JButton(I18n.translate("menu.file.stats.generate")); @@ -98,7 +116,7 @@ public static void show(Gui gui, Map results) { generateStats(gui, checkboxes, topLevelPackage.getText(), syntheticParametersOption.isSelected()); }); - contentPane.add(button, cb1.pos(0, results.size() + 4).weightY(1.0).anchor(GridBagConstraints.SOUTHEAST).build()); + contentPane.add(button, cb1.pos(0, results.size() + 5).weightY(1.0).anchor(GridBagConstraints.SOUTHWEST).build()); // add action listener to each checkbox checkboxes.forEach((key, value) -> value.addActionListener(action -> { diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/stats/StatsGenerator.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/stats/StatsGenerator.java index 99b5572bf..068b8c69d 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/stats/StatsGenerator.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/stats/StatsGenerator.java @@ -55,14 +55,20 @@ public StatsResult generate(ProgressListener progress, Set included Map counts = new HashMap<>(); - int numDone = 0; + String topLevelPackageSlash = topLevelPackage.replace(".", "/"); + int numDone = 0; if (includedMembers.contains(StatsMember.METHODS) || includedMembers.contains(StatsMember.PARAMETERS)) { for (MethodEntry method : entryIndex.getMethods()) { progress.step(numDone++, I18n.translate("type.methods")); - MethodEntry root = entryResolver.resolveEntry(method, ResolutionStrategy.RESOLVE_ROOT).stream().findFirst().orElseThrow(AssertionError::new); - - if (root == method) { + MethodEntry root = entryResolver + .resolveEntry(method, ResolutionStrategy.RESOLVE_ROOT) + .stream() + .findFirst() + .orElseThrow(AssertionError::new); + + ClassEntry clazz = root.getParent(); + if (root == method && this.mapper.deobfuscate(clazz).getPackageName().startsWith(topLevelPackageSlash)) { if (includedMembers.contains(StatsMember.METHODS) && !((MethodDefEntry) method).getAccess().isSynthetic()) { update(counts, method); totalMappable++; @@ -70,7 +76,6 @@ public StatsResult generate(ProgressListener progress, Set included if (includedMembers.contains(StatsMember.PARAMETERS) && (!((MethodDefEntry) method).getAccess().isSynthetic() || includeSynthetic)) { int index = ((MethodDefEntry) method).getAccess().isStatic() ? 0 : 1; - for (TypeDescriptor argument : method.getDesc().getArgumentDescs()) { update(counts, new LocalVariableEntry(method, index, "", true, null)); index += argument.getSize(); @@ -81,6 +86,27 @@ public StatsResult generate(ProgressListener progress, Set included } } + if (includedMembers.contains(StatsMember.FIELDS)) { + for (FieldEntry field : entryIndex.getFields()) { + progress.step(numDone++, I18n.translate("type.fields")); + ClassEntry clazz = field.getParent(); + if (!((FieldDefEntry) field).getAccess().isSynthetic() && this.mapper.deobfuscate(clazz).getPackageName().startsWith(topLevelPackageSlash)) { + update(counts, field); + totalMappable++; + } + } + } + + if (includedMembers.contains(StatsMember.CLASSES)) { + for (ClassEntry clazz : entryIndex.getClasses()) { + progress.step(numDone++, I18n.translate("type.classes")); + if (this.mapper.deobfuscate(clazz).getPackageName().startsWith(topLevelPackageSlash)) { + update(counts, clazz); + totalMappable++; + } + } + } + if (includedMembers.contains(StatsMember.FIELDS)) { for (FieldEntry field : entryIndex.getFields()) { progress.step(numDone++, I18n.translate("type.fields")); diff --git a/enigma/src/main/resources/lang/en_us.json b/enigma/src/main/resources/lang/en_us.json index 4ec2f087e..76afebc2e 100644 --- a/enigma/src/main/resources/lang/en_us.json +++ b/enigma/src/main/resources/lang/en_us.json @@ -28,6 +28,8 @@ "menu.file.export.jar": "Export Jar...", "menu.file.stats": "Mapping Stats...", "menu.file.stats.title": "Mapping Stats", + "menu.file.stats.title_filtered": "Mapping Stats for %s", + "menu.file.stats.filter": "Filter", "menu.file.stats.top_level_package": "Top-Level Package:", "menu.file.stats.synthetic_parameters": "Include Synthetic Parameters", "menu.file.stats.generate": "Generate Diagram", From 226530912d376f000904896cff65d9f0ce92c406 Mon Sep 17 00:00:00 2001 From: ByMartrixX Date: Tue, 15 Mar 2022 20:14:27 -0300 Subject: [PATCH 2/5] Fix mapping stats not skipping anonymous classes Adds indexing of inner & enclosing classes, since it's the only way to properly detect an anonymous class --- .../enigma/gui/stats/StatsGenerator.java | 2 +- .../java/cuchaz/enigma/EnigmaProject.java | 17 ++++++ .../enigma/analysis/index/EntryIndex.java | 2 + .../analysis/index/IndexClassVisitor.java | 14 +++++ .../analysis/index/InnerClassIndex.java | 54 +++++++++++++++++++ .../enigma/analysis/index/JarIndex.java | 31 +++++++++-- .../enigma/analysis/index/JarIndexer.java | 22 ++++++++ 7 files changed, 138 insertions(+), 4 deletions(-) create mode 100644 enigma/src/main/java/cuchaz/enigma/analysis/index/InnerClassIndex.java diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/stats/StatsGenerator.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/stats/StatsGenerator.java index 068b8c69d..b9cb524dd 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/stats/StatsGenerator.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/stats/StatsGenerator.java @@ -141,7 +141,7 @@ public StatsResult generate(ProgressListener progress, Set included } private void update(Map counts, Entry entry) { - if (project.isObfuscated(entry)) { + if (project.isObfuscated(entry) && project.isRenamable(entry) && !project.isSynthetic(entry)) { String parent = mapper.deobfuscate(entry.getAncestry().get(0)).getName().replace('/', '.'); counts.put(parent, counts.getOrDefault(parent, 0) + 1); } diff --git a/enigma/src/main/java/cuchaz/enigma/EnigmaProject.java b/enigma/src/main/java/cuchaz/enigma/EnigmaProject.java index 15d5e9809..cc8cd4768 100644 --- a/enigma/src/main/java/cuchaz/enigma/EnigmaProject.java +++ b/enigma/src/main/java/cuchaz/enigma/EnigmaProject.java @@ -22,7 +22,9 @@ import org.objectweb.asm.tree.ClassNode; import cuchaz.enigma.analysis.EntryReference; +import cuchaz.enigma.analysis.index.InnerClassIndex; import cuchaz.enigma.analysis.index.JarIndex; +import cuchaz.enigma.analysis.index.JarIndexer; import cuchaz.enigma.api.service.NameProposalService; import cuchaz.enigma.api.service.ObfuscationTestService; import cuchaz.enigma.bytecode.translators.TranslationClassVisitor; @@ -153,6 +155,17 @@ public boolean isRenamable(Entry obfEntry) { } } else if (obfEntry instanceof LocalVariableEntry && !((LocalVariableEntry) obfEntry).isArgument()) { return false; + } else if (obfEntry instanceof ClassEntry classEntry) { + InnerClassIndex innerClassIndex = jarIndex.getInnerClassIndex(); + + if (innerClassIndex.isInnerClass(classEntry) && innerClassIndex.hasOuterClassData(classEntry)) { + JarIndexer.InnerClassData innerClassData = innerClassIndex.getInnerClassData(classEntry); + + if (!innerClassData.hasInnerName() && !innerClassData.hasOuterName()) { + // Anonymous classes don't have inner or outer names + return false; + } + } } return this.jarIndex.getEntryIndex().hasEntry(obfEntry); @@ -194,6 +207,10 @@ public boolean isObfuscated(Entry entry) { return true; } + public boolean isSynthetic(Entry entry) { + return jarIndex.getEntryIndex().hasEntry(entry) && jarIndex.getEntryIndex().getEntryAccess(entry).isSynthetic(); + } + public JarExport exportRemappedJar(ProgressListener progress) { Collection classEntries = jarIndex.getEntryIndex().getClasses(); ClassProvider fixingClassProvider = new ObfuscationFixClassProvider(classProvider, jarIndex); diff --git a/enigma/src/main/java/cuchaz/enigma/analysis/index/EntryIndex.java b/enigma/src/main/java/cuchaz/enigma/analysis/index/EntryIndex.java index 0e4cdcfa0..9eb148d77 100644 --- a/enigma/src/main/java/cuchaz/enigma/analysis/index/EntryIndex.java +++ b/enigma/src/main/java/cuchaz/enigma/analysis/index/EntryIndex.java @@ -87,6 +87,8 @@ public AccessFlags getEntryAccess(Entry entry) { return getFieldAccess(fieldEntry); } else if (entry instanceof LocalVariableEntry localVariableEntry) { return getMethodAccess(localVariableEntry.getParent()); + } else if (entry instanceof ClassEntry classEntry) { + return getClassAccess(classEntry); } return null; diff --git a/enigma/src/main/java/cuchaz/enigma/analysis/index/IndexClassVisitor.java b/enigma/src/main/java/cuchaz/enigma/analysis/index/IndexClassVisitor.java index e697182f2..361ad9975 100644 --- a/enigma/src/main/java/cuchaz/enigma/analysis/index/IndexClassVisitor.java +++ b/enigma/src/main/java/cuchaz/enigma/analysis/index/IndexClassVisitor.java @@ -25,6 +25,20 @@ public void visit(int version, int access, String name, String signature, String super.visit(version, access, name, signature, superName, interfaces); } + @Override + public void visitInnerClass(String name, String outerName, String innerName, int access) { + indexer.indexInnerClass(classEntry, new JarIndexer.InnerClassData(name, outerName, innerName, access)); + + super.visitInnerClass(name, outerName, innerName, access); + } + + @Override + public void visitOuterClass(String owner, String name, String descriptor) { + indexer.indexOuterClass(classEntry, new JarIndexer.OuterClassData(owner, name, descriptor)); + + super.visitOuterClass(owner, name, descriptor); + } + @Override public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { indexer.indexField(FieldDefEntry.parse(classEntry, access, name, desc, signature)); diff --git a/enigma/src/main/java/cuchaz/enigma/analysis/index/InnerClassIndex.java b/enigma/src/main/java/cuchaz/enigma/analysis/index/InnerClassIndex.java new file mode 100644 index 000000000..d88736e53 --- /dev/null +++ b/enigma/src/main/java/cuchaz/enigma/analysis/index/InnerClassIndex.java @@ -0,0 +1,54 @@ +package cuchaz.enigma.analysis.index; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; + +import cuchaz.enigma.translation.representation.entry.ClassDefEntry; +import cuchaz.enigma.translation.representation.entry.ClassEntry; + +public class InnerClassIndex implements JarIndexer { + private Multimap innerClasses = ArrayListMultimap.create(); + private Map outerClassesData = new HashMap<>(); + + @Override + public void indexInnerClass(ClassDefEntry classEntry, InnerClassData innerClassData) { + innerClasses.put(classEntry, innerClassData); + } + + @Override + public void indexOuterClass(ClassDefEntry classEntry, OuterClassData outerClassData) { + outerClassesData.put(classEntry, outerClassData); + } + + private Optional> findInnerClassEntry(ClassEntry classEntry) { + return innerClasses.entries().stream().filter(entry -> entry.getValue().name().equals(classEntry.getFullName())).findFirst(); + } + + public boolean isInnerClass(ClassEntry classEntry) { + return findInnerClassEntry(classEntry).isPresent(); + } + + public InnerClassData getInnerClassData(ClassEntry classEntry) { + return findInnerClassEntry(classEntry).map(Map.Entry::getValue).orElse(null); + } + + public ClassDefEntry getOuterClass(ClassEntry classEntry) { + return findInnerClassEntry(classEntry).map(Map.Entry::getKey).orElse(null); + } + + private Optional> findOuterClassDataEntry(ClassEntry classEntry) { + return outerClassesData.entrySet().stream().filter(entry -> entry.getKey().equals(classEntry)).findFirst(); + } + + public boolean hasOuterClassData(ClassEntry classEntry) { + return findOuterClassDataEntry(classEntry).isPresent(); + } + + public OuterClassData getOuterClassData(ClassEntry classEntry) { + return findOuterClassDataEntry(classEntry).map(Map.Entry::getValue).orElse(null); + } +} diff --git a/enigma/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java b/enigma/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java index 60864ba56..0a694323a 100644 --- a/enigma/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java +++ b/enigma/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java @@ -44,6 +44,7 @@ public class JarIndex implements JarIndexer { private final ReferenceIndex referenceIndex; private final BridgeMethodIndex bridgeMethodIndex; private final PackageVisibilityIndex packageVisibilityIndex; + private final InnerClassIndex innerClassIndex; private final EntryResolver entryResolver; private final Collection indexers; @@ -51,13 +52,14 @@ public class JarIndex implements JarIndexer { private final Multimap methodImplementations = HashMultimap.create(); private final ListMultimap childrenByClass; - public JarIndex(EntryIndex entryIndex, InheritanceIndex inheritanceIndex, ReferenceIndex referenceIndex, BridgeMethodIndex bridgeMethodIndex, PackageVisibilityIndex packageVisibilityIndex) { + public JarIndex(EntryIndex entryIndex, InheritanceIndex inheritanceIndex, ReferenceIndex referenceIndex, BridgeMethodIndex bridgeMethodIndex, PackageVisibilityIndex packageVisibilityIndex, InnerClassIndex innerClassIndex) { this.entryIndex = entryIndex; this.inheritanceIndex = inheritanceIndex; this.referenceIndex = referenceIndex; this.bridgeMethodIndex = bridgeMethodIndex; this.packageVisibilityIndex = packageVisibilityIndex; - this.indexers = List.of(entryIndex, inheritanceIndex, referenceIndex, bridgeMethodIndex, packageVisibilityIndex); + this.innerClassIndex = innerClassIndex; + this.indexers = List.of(entryIndex, inheritanceIndex, referenceIndex, bridgeMethodIndex, packageVisibilityIndex, innerClassIndex); this.entryResolver = new IndexEntryResolver(this); this.childrenByClass = ArrayListMultimap.create(); } @@ -68,7 +70,8 @@ public static JarIndex empty() { ReferenceIndex referenceIndex = new ReferenceIndex(); BridgeMethodIndex bridgeMethodIndex = new BridgeMethodIndex(entryIndex, inheritanceIndex, referenceIndex); PackageVisibilityIndex packageVisibilityIndex = new PackageVisibilityIndex(); - return new JarIndex(entryIndex, inheritanceIndex, referenceIndex, bridgeMethodIndex, packageVisibilityIndex); + InnerClassIndex innerClassIndex = new InnerClassIndex(); + return new JarIndex(entryIndex, inheritanceIndex, referenceIndex, bridgeMethodIndex, packageVisibilityIndex, innerClassIndex); } public void indexJar(Set classNames, ClassProvider classProvider, ProgressListener progress) { @@ -175,6 +178,24 @@ public void indexLambda(MethodDefEntry callerEntry, Lambda lambda, ReferenceTarg indexers.forEach(indexer -> indexer.indexLambda(callerEntry, lambda, targetType)); } + @Override + public void indexInnerClass(ClassDefEntry classEntry, InnerClassData innerClassData) { + if (classEntry.isJre()) { + return; + } + + indexers.forEach(indexer -> indexer.indexInnerClass(classEntry, innerClassData)); + } + + @Override + public void indexOuterClass(ClassDefEntry classEntry, OuterClassData outerClassData) { + if (classEntry.isJre()) { + return; + } + + indexers.forEach(indexer -> indexer.indexOuterClass(classEntry, outerClassData)); + } + public EntryIndex getEntryIndex() { return entryIndex; } @@ -195,6 +216,10 @@ public PackageVisibilityIndex getPackageVisibilityIndex() { return packageVisibilityIndex; } + public InnerClassIndex getInnerClassIndex() { + return innerClassIndex; + } + public EntryResolver getEntryResolver() { return entryResolver; } diff --git a/enigma/src/main/java/cuchaz/enigma/analysis/index/JarIndexer.java b/enigma/src/main/java/cuchaz/enigma/analysis/index/JarIndexer.java index 8726fb560..af614fd53 100644 --- a/enigma/src/main/java/cuchaz/enigma/analysis/index/JarIndexer.java +++ b/enigma/src/main/java/cuchaz/enigma/analysis/index/JarIndexer.java @@ -27,6 +27,28 @@ default void indexFieldReference(MethodDefEntry callerEntry, FieldEntry referenc default void indexLambda(MethodDefEntry callerEntry, Lambda lambda, ReferenceTargetType targetType) { } + default void indexInnerClass(ClassDefEntry classEntry, InnerClassData innerClassData) { + } + + default void indexOuterClass(ClassDefEntry classEntry, OuterClassData outerClassData) { + } + default void processIndex(JarIndex index) { } + + record InnerClassData(String name, String innerName, String outerName, int access) { + public boolean hasInnerName() { + return innerName != null; + } + + public boolean hasOuterName() { + return outerName != null; + } + } + + record OuterClassData(String owner, String name, String descriptor) { + public boolean hasEnclosingMethod() { + return name != null && descriptor != null; + } + } } From fd224179dd05566a5b3640ef81f8b4ca8d49d69c Mon Sep 17 00:00:00 2001 From: NebelNidas Date: Sat, 24 Sep 2022 16:48:06 +0200 Subject: [PATCH 3/5] Fix checkstyle --- .../main/java/cuchaz/enigma/gui/dialog/StatsDialog.java | 4 +++- .../main/java/cuchaz/enigma/gui/stats/StatsGenerator.java | 8 +++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/StatsDialog.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/StatsDialog.java index b39b95357..834346725 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/StatsDialog.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/StatsDialog.java @@ -36,6 +36,7 @@ public static void show(Gui gui) { for (StatsMember member : StatsMember.values()) { results.put(member, statsGenerator.generate(listener, Collections.singleton(member), "", false)); } + SwingUtilities.invokeLater(() -> show(gui, results, "")); }); } @@ -89,12 +90,13 @@ public static void show(Gui gui, Map results, String p final StatsGenerator statsGenerator = new StatsGenerator(gui.getController().project); final Map _results = new HashMap<>(); + for (StatsMember member : StatsMember.values()) { _results.put(member, statsGenerator.generate(listener, Collections.singleton(member), UiConfig.getLastTopLevelPackage(), false)); } + SwingUtilities.invokeLater(() -> show(gui, _results, UiConfig.getLastTopLevelPackage())); }); - }); contentPane.add(filterButton, cb1.pos(0, results.size() + 3).anchor(GridBagConstraints.EAST).build()); diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/stats/StatsGenerator.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/stats/StatsGenerator.java index b9cb524dd..486d9a981 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/stats/StatsGenerator.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/stats/StatsGenerator.java @@ -54,10 +54,9 @@ public StatsResult generate(ProgressListener progress, Set included progress.init(totalWork, I18n.translate("progress.stats")); Map counts = new HashMap<>(); - String topLevelPackageSlash = topLevelPackage.replace(".", "/"); - int numDone = 0; + if (includedMembers.contains(StatsMember.METHODS) || includedMembers.contains(StatsMember.PARAMETERS)) { for (MethodEntry method : entryIndex.getMethods()) { progress.step(numDone++, I18n.translate("type.methods")); @@ -66,8 +65,8 @@ public StatsResult generate(ProgressListener progress, Set included .stream() .findFirst() .orElseThrow(AssertionError::new); - ClassEntry clazz = root.getParent(); + if (root == method && this.mapper.deobfuscate(clazz).getPackageName().startsWith(topLevelPackageSlash)) { if (includedMembers.contains(StatsMember.METHODS) && !((MethodDefEntry) method).getAccess().isSynthetic()) { update(counts, method); @@ -76,6 +75,7 @@ public StatsResult generate(ProgressListener progress, Set included if (includedMembers.contains(StatsMember.PARAMETERS) && (!((MethodDefEntry) method).getAccess().isSynthetic() || includeSynthetic)) { int index = ((MethodDefEntry) method).getAccess().isStatic() ? 0 : 1; + for (TypeDescriptor argument : method.getDesc().getArgumentDescs()) { update(counts, new LocalVariableEntry(method, index, "", true, null)); index += argument.getSize(); @@ -90,6 +90,7 @@ public StatsResult generate(ProgressListener progress, Set included for (FieldEntry field : entryIndex.getFields()) { progress.step(numDone++, I18n.translate("type.fields")); ClassEntry clazz = field.getParent(); + if (!((FieldDefEntry) field).getAccess().isSynthetic() && this.mapper.deobfuscate(clazz).getPackageName().startsWith(topLevelPackageSlash)) { update(counts, field); totalMappable++; @@ -100,6 +101,7 @@ public StatsResult generate(ProgressListener progress, Set included if (includedMembers.contains(StatsMember.CLASSES)) { for (ClassEntry clazz : entryIndex.getClasses()) { progress.step(numDone++, I18n.translate("type.classes")); + if (this.mapper.deobfuscate(clazz).getPackageName().startsWith(topLevelPackageSlash)) { update(counts, clazz); totalMappable++; From 9cd4b784fe8ab8e4ef16fc58b17bb032d3a77859 Mon Sep 17 00:00:00 2001 From: NebelNidas Date: Sat, 24 Sep 2022 23:17:40 +0200 Subject: [PATCH 4/5] Improve variable name --- .../src/main/java/cuchaz/enigma/gui/dialog/StatsDialog.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/StatsDialog.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/StatsDialog.java index 834346725..5f030382a 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/StatsDialog.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/StatsDialog.java @@ -89,13 +89,13 @@ public static void show(Gui gui, Map results, String p UiConfig.save(); final StatsGenerator statsGenerator = new StatsGenerator(gui.getController().project); - final Map _results = new HashMap<>(); + final Map filteredResults = new HashMap<>(); for (StatsMember member : StatsMember.values()) { - _results.put(member, statsGenerator.generate(listener, Collections.singleton(member), UiConfig.getLastTopLevelPackage(), false)); + filteredResults.put(member, statsGenerator.generate(listener, Collections.singleton(member), UiConfig.getLastTopLevelPackage(), false)); } - SwingUtilities.invokeLater(() -> show(gui, _results, UiConfig.getLastTopLevelPackage())); + SwingUtilities.invokeLater(() -> show(gui, filteredResults, UiConfig.getLastTopLevelPackage())); }); }); contentPane.add(filterButton, cb1.pos(0, results.size() + 3).anchor(GridBagConstraints.EAST).build()); From 68a8078538ca68addefce34684c37922078c90a5 Mon Sep 17 00:00:00 2001 From: NebelNidas Date: Mon, 26 Sep 2022 21:55:40 +0200 Subject: [PATCH 5/5] Revert "Allow filtering of packages in Mapping Stats window" This reverts commit f992016433d44c2d16244035bd9131ba79e1c8a4. --- .../cuchaz/enigma/gui/dialog/StatsDialog.java | 30 +++------------- .../enigma/gui/stats/StatsGenerator.java | 35 ++----------------- enigma/src/main/resources/lang/en_us.json | 2 -- 3 files changed, 8 insertions(+), 59 deletions(-) diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/StatsDialog.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/StatsDialog.java index 5f030382a..1ab66ef2d 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/StatsDialog.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/StatsDialog.java @@ -37,13 +37,13 @@ public static void show(Gui gui) { results.put(member, statsGenerator.generate(listener, Collections.singleton(member), "", false)); } - SwingUtilities.invokeLater(() -> show(gui, results, "")); + SwingUtilities.invokeLater(() -> show(gui, results)); }); } - public static void show(Gui gui, Map results, String packageName) { + public static void show(Gui gui, Map results) { // init frame - JDialog dialog = new JDialog(gui.getFrame(), packageName.isEmpty() ? I18n.translate("menu.file.stats.title") : I18n.translateFormatted("menu.file.stats.title_filtered", packageName), true); + JDialog dialog = new JDialog(gui.getFrame(), I18n.translate("menu.file.stats.title"), true); Container contentPane = dialog.getContentPane(); contentPane.setLayout(new GridBagLayout()); @@ -80,30 +80,10 @@ public static void show(Gui gui, Map results, String p topLevelPackage.setText(UiConfig.getLastTopLevelPackage()); contentPane.add(topLevelPackage, cb1.pos(0, results.size() + 2).fill(GridBagConstraints.HORIZONTAL).build()); - // Show filter button - JButton filterButton = new JButton(I18n.translate("menu.file.stats.filter")); - filterButton.addActionListener(action -> { - dialog.dispose(); - ProgressDialog.runOffThread(gui.getFrame(), listener -> { - UiConfig.setLastTopLevelPackage(topLevelPackage.getText()); - UiConfig.save(); - - final StatsGenerator statsGenerator = new StatsGenerator(gui.getController().project); - final Map filteredResults = new HashMap<>(); - - for (StatsMember member : StatsMember.values()) { - filteredResults.put(member, statsGenerator.generate(listener, Collections.singleton(member), UiConfig.getLastTopLevelPackage(), false)); - } - - SwingUtilities.invokeLater(() -> show(gui, filteredResults, UiConfig.getLastTopLevelPackage())); - }); - }); - contentPane.add(filterButton, cb1.pos(0, results.size() + 3).anchor(GridBagConstraints.EAST).build()); - // show synthetic members option JCheckBox syntheticParametersOption = new JCheckBox(I18n.translate("menu.file.stats.synthetic_parameters")); syntheticParametersOption.setSelected(UiConfig.shouldIncludeSyntheticParameters()); - contentPane.add(syntheticParametersOption, cb1.pos(0, results.size() + 4).build()); + contentPane.add(syntheticParametersOption, cb1.pos(0, results.size() + 3).build()); // show generate button JButton button = new JButton(I18n.translate("menu.file.stats.generate")); @@ -118,7 +98,7 @@ public static void show(Gui gui, Map results, String p generateStats(gui, checkboxes, topLevelPackage.getText(), syntheticParametersOption.isSelected()); }); - contentPane.add(button, cb1.pos(0, results.size() + 5).weightY(1.0).anchor(GridBagConstraints.SOUTHWEST).build()); + contentPane.add(button, cb1.pos(0, results.size() + 4).weightY(1.0).anchor(GridBagConstraints.SOUTHEAST).build()); // add action listener to each checkbox checkboxes.forEach((key, value) -> value.addActionListener(action -> { diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/stats/StatsGenerator.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/stats/StatsGenerator.java index 486d9a981..44d8dc4de 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/stats/StatsGenerator.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/stats/StatsGenerator.java @@ -54,20 +54,14 @@ public StatsResult generate(ProgressListener progress, Set included progress.init(totalWork, I18n.translate("progress.stats")); Map counts = new HashMap<>(); - String topLevelPackageSlash = topLevelPackage.replace(".", "/"); int numDone = 0; if (includedMembers.contains(StatsMember.METHODS) || includedMembers.contains(StatsMember.PARAMETERS)) { for (MethodEntry method : entryIndex.getMethods()) { progress.step(numDone++, I18n.translate("type.methods")); - MethodEntry root = entryResolver - .resolveEntry(method, ResolutionStrategy.RESOLVE_ROOT) - .stream() - .findFirst() - .orElseThrow(AssertionError::new); - ClassEntry clazz = root.getParent(); - - if (root == method && this.mapper.deobfuscate(clazz).getPackageName().startsWith(topLevelPackageSlash)) { + MethodEntry root = entryResolver.resolveEntry(method, ResolutionStrategy.RESOLVE_ROOT).stream().findFirst().orElseThrow(AssertionError::new); + + if (root == method) { if (includedMembers.contains(StatsMember.METHODS) && !((MethodDefEntry) method).getAccess().isSynthetic()) { update(counts, method); totalMappable++; @@ -86,29 +80,6 @@ public StatsResult generate(ProgressListener progress, Set included } } - if (includedMembers.contains(StatsMember.FIELDS)) { - for (FieldEntry field : entryIndex.getFields()) { - progress.step(numDone++, I18n.translate("type.fields")); - ClassEntry clazz = field.getParent(); - - if (!((FieldDefEntry) field).getAccess().isSynthetic() && this.mapper.deobfuscate(clazz).getPackageName().startsWith(topLevelPackageSlash)) { - update(counts, field); - totalMappable++; - } - } - } - - if (includedMembers.contains(StatsMember.CLASSES)) { - for (ClassEntry clazz : entryIndex.getClasses()) { - progress.step(numDone++, I18n.translate("type.classes")); - - if (this.mapper.deobfuscate(clazz).getPackageName().startsWith(topLevelPackageSlash)) { - update(counts, clazz); - totalMappable++; - } - } - } - if (includedMembers.contains(StatsMember.FIELDS)) { for (FieldEntry field : entryIndex.getFields()) { progress.step(numDone++, I18n.translate("type.fields")); diff --git a/enigma/src/main/resources/lang/en_us.json b/enigma/src/main/resources/lang/en_us.json index 76afebc2e..4ec2f087e 100644 --- a/enigma/src/main/resources/lang/en_us.json +++ b/enigma/src/main/resources/lang/en_us.json @@ -28,8 +28,6 @@ "menu.file.export.jar": "Export Jar...", "menu.file.stats": "Mapping Stats...", "menu.file.stats.title": "Mapping Stats", - "menu.file.stats.title_filtered": "Mapping Stats for %s", - "menu.file.stats.filter": "Filter", "menu.file.stats.top_level_package": "Top-Level Package:", "menu.file.stats.synthetic_parameters": "Include Synthetic Parameters", "menu.file.stats.generate": "Generate Diagram",