diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java index 1b4e80505..6d46d7b88 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java @@ -396,14 +396,14 @@ public class ModVisitor extends AbstractVisitor { return filledArr; } - private static boolean allArgsNull(InsnNode insn) { + private static boolean allArgsNull(ConstructorInsn insn) { for (InsnArg insnArg : insn.getArguments()) { if (insnArg.isLiteral()) { LiteralArg lit = (LiteralArg) insnArg; if (lit.getLiteral() != 0) { return false; } - } else if (!insnArg.isThis()) { + } else { return false; } } diff --git a/jadx-core/src/test/java/jadx/tests/external/BaseExternalTest.java b/jadx-core/src/test/java/jadx/tests/external/BaseExternalTest.java index e1d59882f..90ac8de9e 100644 --- a/jadx-core/src/test/java/jadx/tests/external/BaseExternalTest.java +++ b/jadx-core/src/test/java/jadx/tests/external/BaseExternalTest.java @@ -25,6 +25,7 @@ import jadx.core.dex.visitors.IDexTreeVisitor; import jadx.core.utils.exceptions.JadxRuntimeException; import jadx.tests.api.IntegrationTest; +import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; @@ -58,7 +59,7 @@ public abstract class BaseExternalTest extends IntegrationTest { } else { Pattern clsPtrn = Pattern.compile(clsPatternStr); Pattern mthPtrn = mthPatternStr == null ? null : Pattern.compile(mthPatternStr); - processMthByPatterns(jadx, clsPtrn, mthPtrn); + processByPatterns(jadx, clsPtrn, mthPtrn); } printErrorReport(jadx); } @@ -69,44 +70,53 @@ public abstract class BaseExternalTest extends IntegrationTest { } } - private void processMthByPatterns(JadxDecompiler jadx, Pattern clsPattern, @Nullable Pattern mthPattern) { + private void processByPatterns(JadxDecompiler jadx, Pattern clsPattern, @Nullable Pattern mthPattern) { List passes = Jadx.getPassesList(jadx.getArgs()); RootNode root = JadxInternalAccess.getRoot(jadx); + int processed = 0; for (ClassNode classNode : root.getClasses(true)) { String clsFullName = classNode.getClassInfo().getFullName(); if (clsPattern.matcher(clsFullName).matches()) { - classNode.load(); - boolean decompile = false; - if (mthPattern == null) { - decompile = true; - } else { - for (MethodNode mth : classNode.getMethods()) { - if (mthPattern.matcher(mth.getName()).matches()) { - decompile = true; - break; - } - } - } - if (decompile) { - for (IDexTreeVisitor visitor : passes) { - DepthTraversal.visit(visitor, classNode); - } - try { - new CodeGen().visit(classNode); - } catch (Exception e) { - throw new JadxRuntimeException("Codegen failed", e); - } - LOG.warn("\n Print class: {}, {}", classNode.getFullName(), classNode.dex()); - if (mthPattern != null) { - printMethods(classNode, mthPattern); - } else { - LOG.info("Code: \n{}", classNode.getCode()); - } - checkCode(classNode); -// SaveCode.save(jadx.getArgs().getOutDirSrc(), jadx.getArgs(), classNode); + if (processCls(mthPattern, passes, classNode)) { + processed++; } } } + assertThat("No classes processed", processed, greaterThan(0)); + } + + private boolean processCls(@Nullable Pattern mthPattern, List passes, ClassNode classNode) { + classNode.load(); + boolean decompile = false; + if (mthPattern == null) { + decompile = true; + } else { + for (MethodNode mth : classNode.getMethods()) { + if (mthPattern.matcher(mth.getName()).matches()) { + decompile = true; + break; + } + } + } + if (!decompile) { + return false; + } + for (IDexTreeVisitor visitor : passes) { + DepthTraversal.visit(visitor, classNode); + } + try { + new CodeGen().visit(classNode); + } catch (Exception e) { + throw new JadxRuntimeException("Codegen failed", e); + } + LOG.warn("\n Print class: {}, {}", classNode.getFullName(), classNode.dex()); + if (mthPattern != null) { + printMethods(classNode, mthPattern); + } else { + LOG.info("Code: \n{}", classNode.getCode()); + } + checkCode(classNode); + return true; } private void printMethods(ClassNode classNode, @NotNull Pattern mthPattern) { diff --git a/jadx-core/src/test/java/jadx/tests/integration/inner/TestOuterConstructorCall.java b/jadx-core/src/test/java/jadx/tests/integration/inner/TestOuterConstructorCall.java new file mode 100644 index 000000000..4e2f2f2c1 --- /dev/null +++ b/jadx-core/src/test/java/jadx/tests/integration/inner/TestOuterConstructorCall.java @@ -0,0 +1,35 @@ +package jadx.tests.integration.inner; + +import org.junit.Test; + +import jadx.core.dex.nodes.ClassNode; +import jadx.tests.api.IntegrationTest; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertThat; + +public class TestOuterConstructorCall extends IntegrationTest { + + public static class TestCls { + private TestCls(Inner inner) { + System.out.println(inner); + } + + private class Inner { + private TestCls test() { + return new TestCls(this); + } + } + } + + @Test + public void test() { + ClassNode cls = getClassNode(TestCls.class); + String code = cls.getCode().toString(); + + assertThat(code, containsString("private class Inner {")); + assertThat(code, containsString("return new TestOuterConstructorCall$TestCls(this);")); + assertThat(code, not(containsString("synthetic"))); + } +}