diff --git a/CHANGELOG.md b/CHANGELOG.md index 9435b9a4a..c8228a419 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -209,3 +209,26 @@ With this release, we made quite a few changes in the direction of supporting mo - updated gradle and fixed deprecations - updated dependencies - vineflower: `1.10.0` -> `1.10.1` + +# 2.4.1 + +As always, we need a quick bugfix release before the next big update. `2.4.1` fixes some long-standing issues! + +- fixed javadocs applied to parameters with proposed names becoming detached from the parameter due to being saved incorrect in the Enigma mappings format +- fixed the GUI still attempting to confirm warnings when a fatal error is present in a validation +- updated dependencies + - guava: `33.0.0` -> `33.2.1` + - proguard: `7.4.0` -> `7.5.0` + +# 2.4.2 + +More bugfixes. I work so hard for my beloved users. + +- fixed javadoc dialog not scaling properly +- fixed invalid data being appended to exports of the stats tree +- removed an extra debug print statement that was sitting in the mass package renamer +- updated dependencies + - quilt config: `1.3.0` -> `1.3.2` + - junit: `5.9.3` -> `5.10.3` + - hamcrest: `2.2` -> `3.0` + - jimfs: `1.2` -> `1.3.0` diff --git a/build.gradle b/build.gradle index feb7efde9..6d30d787c 100644 --- a/build.gradle +++ b/build.gradle @@ -35,7 +35,7 @@ subprojects { } group = 'org.quiltmc' - version = '2.4.1' + version = '2.4.2' var ENV = System.getenv() version = version + (ENV.GITHUB_ACTIONS ? (ENV.SNAPSHOTS_URL ? "-SNAPSHOT" : "") : "+local") diff --git a/enigma-swing/src/main/java/org/quiltmc/enigma/gui/dialog/JavadocDialog.java b/enigma-swing/src/main/java/org/quiltmc/enigma/gui/dialog/JavadocDialog.java index 595f2e376..d715e7e90 100644 --- a/enigma-swing/src/main/java/org/quiltmc/enigma/gui/dialog/JavadocDialog.java +++ b/enigma-swing/src/main/java/org/quiltmc/enigma/gui/dialog/JavadocDialog.java @@ -65,7 +65,7 @@ private JavadocDialog(JFrame parent, GuiController controller, Entry entry, S this.close(); } })); - this.text.setFont(Config.currentFonts().editor.value()); + this.text.setFont(ScaleUtil.scaleFont(Config.currentFonts().editor.value())); // buttons panel JPanel buttonsPanel = new JPanel(); diff --git a/enigma-swing/src/main/java/org/quiltmc/enigma/gui/util/PackageRenamer.java b/enigma-swing/src/main/java/org/quiltmc/enigma/gui/util/PackageRenamer.java index 1f314319c..d807cdfc6 100644 --- a/enigma-swing/src/main/java/org/quiltmc/enigma/gui/util/PackageRenamer.java +++ b/enigma-swing/src/main/java/org/quiltmc/enigma/gui/util/PackageRenamer.java @@ -186,7 +186,6 @@ private void handleNode(int divergenceIndex, boolean rename, String[] oldPackage // skips all classes that do not match the exact package being renamed if (this.mode == Mode.MOVE) { if (!oldName.equals(String.join("/", oldPackageNames) + "/" + classNode.getDeobfEntry().getSimpleName())) { - System.out.println("ignoring: " + oldName); return; } } diff --git a/enigma/src/main/java/org/quiltmc/enigma/api/stats/StatsTree.java b/enigma/src/main/java/org/quiltmc/enigma/api/stats/StatsTree.java index 56eeaea09..aaa8749d9 100644 --- a/enigma/src/main/java/org/quiltmc/enigma/api/stats/StatsTree.java +++ b/enigma/src/main/java/org/quiltmc/enigma/api/stats/StatsTree.java @@ -13,7 +13,7 @@ public static class Node { private String name; private T value; private List> children = new ArrayList<>(); - private final Map> namedChildren = new HashMap<>(); + private final transient Map> namedChildren = new HashMap<>(); public Node(String name, T value) { this.name = name; diff --git a/enigma/src/main/java/org/quiltmc/enigma/api/translation/mapping/serde/enigma/EnigmaMappingsReader.java b/enigma/src/main/java/org/quiltmc/enigma/api/translation/mapping/serde/enigma/EnigmaMappingsReader.java index e220b8aa7..a4cc6dbbb 100644 --- a/enigma/src/main/java/org/quiltmc/enigma/api/translation/mapping/serde/enigma/EnigmaMappingsReader.java +++ b/enigma/src/main/java/org/quiltmc/enigma/api/translation/mapping/serde/enigma/EnigmaMappingsReader.java @@ -311,7 +311,10 @@ private static MappingPair parseArgument(@N } LocalVariableEntry obfuscatedEntry = new LocalVariableEntry(ownerEntry, Integer.parseInt(tokens[1])); - String mapping = tokens[2]; + String mapping = null; + if (tokens.length > 2) { + mapping = tokens[2]; + } return new MappingPair<>(obfuscatedEntry, new RawEntryMapping(mapping)); } diff --git a/enigma/src/main/java/org/quiltmc/enigma/api/translation/mapping/serde/enigma/EnigmaMappingsWriter.java b/enigma/src/main/java/org/quiltmc/enigma/api/translation/mapping/serde/enigma/EnigmaMappingsWriter.java index b28ed3d09..451db2c53 100644 --- a/enigma/src/main/java/org/quiltmc/enigma/api/translation/mapping/serde/enigma/EnigmaMappingsWriter.java +++ b/enigma/src/main/java/org/quiltmc/enigma/api/translation/mapping/serde/enigma/EnigmaMappingsWriter.java @@ -219,7 +219,7 @@ protected void writeEntry(PrintWriter writer, EntryTree mappings, line = this.writeMethod(methodEntry, mapping); } else if (entry instanceof FieldEntry fieldEntry) { line = this.writeField(fieldEntry, mapping); - } else if (entry instanceof LocalVariableEntry varEntry && mapping.targetName() != null) { + } else if (entry instanceof LocalVariableEntry varEntry) { line = this.writeArgument(varEntry, mapping); } @@ -292,7 +292,13 @@ protected String writeField(FieldEntry entry, @Nonnull EntryMapping mapping) { } protected String writeArgument(LocalVariableEntry entry, @Nonnull EntryMapping mapping) { - return EnigmaFormat.PARAMETER + " " + entry.getIndex() + ' ' + mapping.targetName(); + StringBuilder builder = new StringBuilder(EnigmaFormat.PARAMETER + " "); + builder.append(entry.getIndex()).append(" "); + if (mapping.targetName() != null) { + builder.append(mapping.targetName()).append(' '); + } + + return builder.toString(); } private void writeMapping(StringBuilder builder, EntryMapping mapping) { diff --git a/enigma/src/main/java/org/quiltmc/enigma/util/validation/ValidationContext.java b/enigma/src/main/java/org/quiltmc/enigma/util/validation/ValidationContext.java index 37680dd06..82e3d0bf3 100644 --- a/enigma/src/main/java/org/quiltmc/enigma/util/validation/ValidationContext.java +++ b/enigma/src/main/java/org/quiltmc/enigma/util/validation/ValidationContext.java @@ -66,18 +66,23 @@ public void raise(Message message, Object... args) { public boolean canProceed() { List messagesCopy = new ArrayList<>(this.messages); - if (this.verifyWarnings) { - for (ParameterizedMessage m : messagesCopy) { - if (m.getType() == Message.Type.WARNING) { - this.messages.remove(m); - if (!this.notifier.verifyWarning(m)) { - return false; + boolean hasError = this.messages.stream().anyMatch(m -> m.message().getType() == Message.Type.ERROR); + if (hasError) { + return false; + } else { + if (this.verifyWarnings) { + for (ParameterizedMessage m : messagesCopy) { + if (m.getType() == Message.Type.WARNING) { + this.messages.remove(m); + if (!this.notifier.verifyWarning(m)) { + return false; + } } } } - } - return this.messages.stream().noneMatch(m -> m.message().getType() == Message.Type.ERROR); + return true; + } } /** diff --git a/enigma/src/test/java/org/quiltmc/enigma/translation/mapping/TestReadWriteCycle.java b/enigma/src/test/java/org/quiltmc/enigma/translation/mapping/TestReadWriteCycle.java index edd6471ec..ae40b089a 100644 --- a/enigma/src/test/java/org/quiltmc/enigma/translation/mapping/TestReadWriteCycle.java +++ b/enigma/src/test/java/org/quiltmc/enigma/translation/mapping/TestReadWriteCycle.java @@ -1,5 +1,6 @@ package org.quiltmc.enigma.translation.mapping; +import org.quiltmc.enigma.TestEntryFactory; import org.quiltmc.enigma.api.Enigma; import org.quiltmc.enigma.api.ProgressListener; import org.quiltmc.enigma.api.service.ReadWriteService; @@ -14,6 +15,7 @@ import org.quiltmc.enigma.api.translation.representation.entry.ClassEntry; import org.quiltmc.enigma.api.translation.representation.entry.Entry; import org.quiltmc.enigma.api.translation.representation.entry.FieldEntry; +import org.quiltmc.enigma.api.translation.representation.entry.LocalVariableEntry; import org.quiltmc.enigma.api.translation.representation.entry.MethodEntry; import org.quiltmc.enigma.util.Pair; import org.junit.jupiter.api.Assertions; @@ -35,6 +37,11 @@ public class TestReadWriteCycle { new EntryMapping("alpha/beta/charlie", "this is a test class", TokenType.DEOBFUSCATED, null) ); + private final Pair testProposedClazz = new Pair<>( + new ClassEntry("a/b/c/d"), + new EntryMapping("alpha/beta/charlie/delta", "this is a test class!", TokenType.JAR_PROPOSED, "enigma:fake_plugin") + ); + private final Pair testField1 = new Pair<>( FieldEntry.parse("a/b/c", "field1", "I"), new EntryMapping("mapped1", "this is field 1", TokenType.DEOBFUSCATED, null) @@ -45,6 +52,11 @@ public class TestReadWriteCycle { new EntryMapping("mapped2", "this is field 2", TokenType.DEOBFUSCATED, null) ); + private final Pair testProposedField = new Pair<>( + FieldEntry.parse("a/b/c", "proposedField", "I"), + new EntryMapping("proposed1", "this is a proposed field", TokenType.JAR_PROPOSED, "enigma:fake_plugin") + ); + private final Pair testMethod1 = new Pair<>( MethodEntry.parse("a/b/c", "method1", "()V"), new EntryMapping("mapped3", "this is method1", TokenType.DEOBFUSCATED, null) @@ -55,6 +67,26 @@ public class TestReadWriteCycle { new EntryMapping("mapped4", "this is method 2", TokenType.DEOBFUSCATED, null) ); + private final Pair testMethod3 = new Pair<>( + MethodEntry.parse("a/b/c", "method3", "(IZ)V"), + new EntryMapping("mapped5", "this is method 3", TokenType.DEOBFUSCATED, null) + ); + + private final Pair testProposedMethod = new Pair<>( + MethodEntry.parse("a/b/c", "proposedMethod", "()V"), + new EntryMapping("proposed2", "this is a proposed method", TokenType.JAR_PROPOSED, "enigma:fake_plugin") + ); + + private final Pair testNormalParameter = new Pair<>( + TestEntryFactory.newParameter(this.testMethod3.a(), 0), + new EntryMapping("mapped6", "this is a normal parameter", TokenType.DEOBFUSCATED, null) + ); + + private final Pair testProposedParameter = new Pair<>( + TestEntryFactory.newParameter(this.testMethod3.a(), 1), + new EntryMapping("mapped7", "this is a proposed parameter", TokenType.JAR_PROPOSED, "enigma:fake_plugin") + ); + private void insertMapping(EntryTree mappings, Pair, EntryMapping> mappingPair) { mappings.insert(mappingPair.a(), mappingPair.b()); } @@ -63,16 +95,28 @@ private void testReadWriteCycle(ReadWriteService readWriteService, String tmpNam //construct some known mappings to test with EntryTree testMappings = new HashEntryTree<>(); this.insertMapping(testMappings, this.testClazz); + this.insertMapping(testMappings, this.testProposedClazz); this.insertMapping(testMappings, this.testField1); this.insertMapping(testMappings, this.testField2); + this.insertMapping(testMappings, this.testProposedField); this.insertMapping(testMappings, this.testMethod1); this.insertMapping(testMappings, this.testMethod2); + this.insertMapping(testMappings, this.testMethod3); + this.insertMapping(testMappings, this.testProposedMethod); + this.insertMapping(testMappings, this.testNormalParameter); + this.insertMapping(testMappings, this.testProposedParameter); Assertions.assertTrue(testMappings.contains(this.testClazz.a()), "Test mapping insertion failed: testClazz"); + Assertions.assertTrue(testMappings.contains(this.testProposedClazz.a()), "Test mapping insertion failed: testProposedClazz"); Assertions.assertTrue(testMappings.contains(this.testField1.a()), "Test mapping insertion failed: testField1"); Assertions.assertTrue(testMappings.contains(this.testField2.a()), "Test mapping insertion failed: testField2"); + Assertions.assertTrue(testMappings.contains(this.testProposedField.a()), "Test mapping insertion failed: testProposedField"); Assertions.assertTrue(testMappings.contains(this.testMethod1.a()), "Test mapping insertion failed: testMethod1"); Assertions.assertTrue(testMappings.contains(this.testMethod2.a()), "Test mapping insertion failed: testMethod2"); + Assertions.assertTrue(testMappings.contains(this.testMethod3.a()), "Test mapping insertion failed: testMethod3"); + Assertions.assertTrue(testMappings.contains(this.testProposedMethod.a()), "Test mapping insertion failed: testProposedMethod"); + Assertions.assertTrue(testMappings.contains(this.testNormalParameter.a()), "Test mapping insertion failed: testNormalParameter"); + Assertions.assertTrue(testMappings.contains(this.testProposedParameter.a()), "Test mapping insertion failed: testProposedParameter"); File tempFile = File.createTempFile("readWriteCycle", tmpNameSuffix); tempFile.delete(); //remove the auto created file @@ -83,22 +127,40 @@ private void testReadWriteCycle(ReadWriteService readWriteService, String tmpNam EntryTree loadedMappings = readWriteService.read(tempFile.toPath(), ProgressListener.createEmpty()); Assertions.assertTrue(loadedMappings.contains(this.testClazz.a()), "Loaded mappings don't contain testClazz"); + Assertions.assertTrue(loadedMappings.contains(this.testProposedClazz.a()), "Loaded mappings don't contain testProposedClazz"); Assertions.assertTrue(loadedMappings.contains(this.testField1.a()), "Loaded mappings don't contain testField1"); Assertions.assertTrue(loadedMappings.contains(this.testField2.a()), "Loaded mappings don't contain testField2"); + Assertions.assertTrue(loadedMappings.contains(this.testProposedField.a()), "Loaded mappings don't contain testProposedField"); Assertions.assertTrue(loadedMappings.contains(this.testMethod1.a()), "Loaded mappings don't contain testMethod1"); Assertions.assertTrue(loadedMappings.contains(this.testMethod2.a()), "Loaded mappings don't contain testMethod2"); + Assertions.assertTrue(loadedMappings.contains(this.testMethod3.a()), "Loaded mappings don't contain testMethod3"); + Assertions.assertTrue(loadedMappings.contains(this.testProposedMethod.a()), "Loaded mappings don't contain testProposedMethod"); + Assertions.assertTrue(loadedMappings.contains(this.testNormalParameter.a()), "Loaded mappings don't contain testNormalParameter"); + Assertions.assertTrue(loadedMappings.contains(this.testProposedParameter.a()), "Loaded mappings don't contain testProposedParameter"); Assertions.assertEquals(this.testClazz.b().targetName(), loadedMappings.get(this.testClazz.a()).targetName(), "Incorrect mapping: testClazz"); + // note: proposed class name will not be saved Assertions.assertEquals(this.testField1.b().targetName(), loadedMappings.get(this.testField1.a()).targetName(), "Incorrect mapping: testField1"); Assertions.assertEquals(this.testField2.b().targetName(), loadedMappings.get(this.testField2.a()).targetName(), "Incorrect mapping: testField2"); + // note: proposed field name will not be saved Assertions.assertEquals(this.testMethod1.b().targetName(), loadedMappings.get(this.testMethod1.a()).targetName(), "Incorrect mapping: testMethod1"); Assertions.assertEquals(this.testMethod2.b().targetName(), loadedMappings.get(this.testMethod2.a()).targetName(), "Incorrect mapping: testMethod2"); + Assertions.assertEquals(this.testMethod3.b().targetName(), loadedMappings.get(this.testMethod3.a()).targetName(), "Incorrect mapping: testMethod3"); + // note: proposed method name will not be saved + Assertions.assertEquals(this.testNormalParameter.b().targetName(), loadedMappings.get(this.testNormalParameter.a()).targetName(), "Incorrect mapping: testNormalParameter"); + // note: proposed parameter name will not be saved Assertions.assertEquals(this.testClazz.b().javadoc(), loadedMappings.get(this.testClazz.a()).javadoc(), "Incorrect javadoc: testClazz"); + Assertions.assertEquals(this.testProposedClazz.b().javadoc(), loadedMappings.get(this.testProposedClazz.a()).javadoc(), "Incorrect javadoc: testProposedClazz"); Assertions.assertEquals(this.testField1.b().javadoc(), loadedMappings.get(this.testField1.a()).javadoc(), "Incorrect javadoc: testField1"); Assertions.assertEquals(this.testField2.b().javadoc(), loadedMappings.get(this.testField2.a()).javadoc(), "Incorrect javadoc: testField2"); + Assertions.assertEquals(this.testProposedField.b().javadoc(), loadedMappings.get(this.testProposedField.a()).javadoc(), "Incorrect javadoc: testProposedField"); Assertions.assertEquals(this.testMethod1.b().javadoc(), loadedMappings.get(this.testMethod1.a()).javadoc(), "Incorrect javadoc: testMethod1"); Assertions.assertEquals(this.testMethod2.b().javadoc(), loadedMappings.get(this.testMethod2.a()).javadoc(), "Incorrect javadoc: testMethod2"); + Assertions.assertEquals(this.testMethod3.b().javadoc(), loadedMappings.get(this.testMethod3.a()).javadoc(), "Incorrect javadoc: testMethod3"); + Assertions.assertEquals(this.testProposedMethod.b().javadoc(), loadedMappings.get(this.testProposedMethod.a()).javadoc(), "Incorrect javadoc: testProposedMethod"); + Assertions.assertEquals(this.testNormalParameter.b().javadoc(), loadedMappings.get(this.testNormalParameter.a()).javadoc(), "Incorrect javadoc: testNormalParameter"); + Assertions.assertEquals(this.testProposedParameter.b().javadoc(), loadedMappings.get(this.testProposedParameter.a()).javadoc(), "Incorrect javadoc: testProposedParameter"); tempFile.delete(); } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index dc42af041..4c927cdfc 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -10,16 +10,16 @@ syntaxpain = "0.1.5" swing_dpi = "0.10" fontchooser = "2.5.2" tinylog = "2.6.2" -quilt_config = "1.3.0" +quilt_config = "1.3.2" vineflower = "1.10.1" cfr = "0.2.2" procyon = "0.6.0" proguard = "7.5.0" -junit = "5.9.3" -hamcrest = "2.2" -jimfs = "1.2" +junit = "5.10.3" +hamcrest = "3.0" +jimfs = "1.3.0" [libraries] guava = { module = "com.google.guava:guava", version.ref = "guava" }