diff --git a/enigma/build.gradle b/enigma/build.gradle index 8baccbd9..af4e398a 100644 --- a/enigma/build.gradle +++ b/enigma/build.gradle @@ -12,15 +12,15 @@ dependencies { implementation 'net.fabricmc:cfr:0.2.2' implementation 'org.vineflower:vineflower:1.10.0' - implementation ('io.github.skylot:jadx-core:1.5.0-20240227.173751-9') { + implementation ('io.github.skylot:jadx-core:1.5.0-20240408.212728-12') { exclude group: 'com.android.tools.build', module: 'aapt2-proto' exclude group: 'com.google.protobuf', module: 'protobuf-java' } - implementation ('io.github.skylot:jadx-java-input:1.5.0-20240227.173751-9') { + implementation ('io.github.skylot:jadx-java-input:1.5.0-20240408.212728-12') { exclude group: 'com.android.tools.build', module: 'aapt2-proto' exclude group: 'io.github.skylot', module: 'raung-disasm' } - implementation 'io.github.skylot:jadx-input-api:1.5.0-20240227.173751-9' // Pin version (would pull 1.5.0-SNAPSHOT otherwise) + implementation 'io.github.skylot:jadx-input-api:1.5.0-20240408.212728-12' // Pin version (would pull 1.5.0-SNAPSHOT otherwise) proGuard 'com.guardsquare:proguard-base:7.4.0-beta02' diff --git a/enigma/src/main/java/cuchaz/enigma/source/jadx/JadxDecompiler.java b/enigma/src/main/java/cuchaz/enigma/source/jadx/JadxDecompiler.java index e2b2151e..13f886c8 100644 --- a/enigma/src/main/java/cuchaz/enigma/source/jadx/JadxDecompiler.java +++ b/enigma/src/main/java/cuchaz/enigma/source/jadx/JadxDecompiler.java @@ -34,6 +34,8 @@ private JadxArgs createJadxArgs(EntryRemapper mapper, JadxHelper jadxHelper) { args.setInlineMethods(false); args.setRespectBytecodeAccModifiers(true); args.setRenameValid(false); + args.setCodeIndentStr("\t"); + args.setCodeNewLineStr("\n"); // JEditorPane is hardcoded to \n args.mapper = mapper; args.jadxHelper = jadxHelper; diff --git a/enigma/src/main/java/cuchaz/enigma/source/jadx/JadxJavadocProvider.java b/enigma/src/main/java/cuchaz/enigma/source/jadx/JadxJavadocProvider.java index 30dc6b36..3e491830 100644 --- a/enigma/src/main/java/cuchaz/enigma/source/jadx/JadxJavadocProvider.java +++ b/enigma/src/main/java/cuchaz/enigma/source/jadx/JadxJavadocProvider.java @@ -2,12 +2,14 @@ import java.util.Collection; +import jadx.api.data.CommentStyle; import jadx.api.plugins.JadxPlugin; import jadx.api.plugins.JadxPluginContext; import jadx.api.plugins.JadxPluginInfo; import jadx.api.plugins.pass.JadxPassInfo; import jadx.api.plugins.pass.impl.OrderedJadxPassInfo; import jadx.api.plugins.pass.types.JadxPreparePass; +import jadx.core.dex.attributes.nodes.NotificationAttrNode; import jadx.core.dex.nodes.ClassNode; import jadx.core.dex.nodes.FieldNode; import jadx.core.dex.nodes.MethodNode; @@ -68,7 +70,7 @@ private void processClass(ClassNode cls) { if (mapping.javadoc() != null && !mapping.javadoc().isBlank()) { // TODO: Once JADX supports records, add @param tags for components - cls.addCodeComment(mapping.javadoc().trim()); + attachJavadoc(cls, mapping.javadoc()); } for (FieldNode field : cls.getFields()) { @@ -84,7 +86,7 @@ private void processField(FieldNode field) { EntryMapping mapping = mapper.getDeobfMapping(jadxHelper.fieldEntryOf(field)); if (mapping.javadoc() != null && !mapping.javadoc().isBlank()) { - field.addCodeComment(mapping.javadoc().trim()); + attachJavadoc(field, mapping.javadoc()); } } @@ -119,11 +121,15 @@ private void processMethod(MethodNode method) { } } - javadoc = builder.toString().trim(); + javadoc = builder.toString(); if (!javadoc.isBlank()) { - method.addCodeComment(javadoc); + attachJavadoc(method, javadoc); } } + + private void attachJavadoc(NotificationAttrNode target, String javadoc) { + target.addCodeComment(javadoc.trim(), CommentStyle.JAVADOC); + } } } diff --git a/enigma/src/main/java/cuchaz/enigma/source/jadx/JadxSource.java b/enigma/src/main/java/cuchaz/enigma/source/jadx/JadxSource.java index 060e5a21..c791cf7d 100644 --- a/enigma/src/main/java/cuchaz/enigma/source/jadx/JadxSource.java +++ b/enigma/src/main/java/cuchaz/enigma/source/jadx/JadxSource.java @@ -2,10 +2,9 @@ import java.util.function.Function; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.objectweb.asm.tree.ClassNode; +import javax.annotation.Nullable; + import jadx.api.ICodeInfo; -import jadx.api.ICodeWriter; import jadx.api.JadxArgs; import jadx.api.JadxDecompiler; import jadx.api.JavaClass; @@ -16,6 +15,7 @@ import jadx.core.dex.nodes.FieldNode; import jadx.core.dex.nodes.MethodNode; import jadx.plugins.input.java.JavaInputPlugin; +import org.objectweb.asm.tree.ClassNode; import cuchaz.enigma.source.Source; import cuchaz.enigma.source.SourceIndex; @@ -36,26 +36,6 @@ public class JadxSource implements Source { private final JadxHelper jadxHelper; private SourceIndex index; - /* - * JADX uses the system default line ending, but JEditorPane does not (seems to be hardcoded to \n). - * This causes tokens to be offset by one char per preceding line, since Windows' \r\n is one char longer than plain \n. - * Unfortunately, the only way of making JADX use a different value is by adjusting the corresponding system property, - * which we can't leave in a modified as it may cause issues elsewhere in the program. - * Thus, we force-load the NL constant now to initialize it to \n and immediately reset the system property again. - * TODO: Remove once https://github.com/skylot/jadx/issues/1948 is addressed. - */ - static { - String propertyKey = "line.separator"; - String oldLineSeparator = System.getProperty(propertyKey); - System.setProperty(propertyKey, "\n"); - - if (!ICodeWriter.NL.equals("\n")) { - throw new AssertionError("NL constant not initialized to \\n"); - } - - System.getProperties().setProperty(propertyKey, oldLineSeparator); - } - public JadxSource(SourceSettings settings, Function jadxArgsFactory, ClassNode classNode, @Nullable EntryRemapper mapper, JadxHelper jadxHelper) { this.settings = settings; this.jadxArgsFactory = jadxArgsFactory; @@ -136,7 +116,7 @@ private void processAnnotatedElement(int pos, ICodeAnnotation ann, ICodeInfo cod index.addReference(token, methodEntryOf(mth), classEntryOf(mth.getParentClass())); } } else if (ann instanceof VarNode var) { - if (!var.getMth().collectArgsWithoutLoading().contains(var)) return; + if (!var.getMth().collectArgNodes().contains(var)) return; Token token = new Token(pos, pos + var.getName().length(), var.getName()); if (pos == var.getDefPosition()) {