Commit 69eb57cb authored by Skylot's avatar Skylot

Fix sythetic methods inline

parent e3a10391
......@@ -3,6 +3,7 @@ package jadx.dex.visitors;
import jadx.dex.attributes.AttributeFlag;
import jadx.dex.attributes.IAttribute;
import jadx.dex.attributes.MethodInlineAttr;
import jadx.dex.info.AccessInfo;
import jadx.dex.instructions.InsnType;
import jadx.dex.nodes.BlockNode;
import jadx.dex.nodes.InsnNode;
......@@ -13,34 +14,30 @@ public class MethodInlinerVisitor extends AbstractVisitor {
@Override
public void visit(MethodNode mth) throws JadxException {
if (mth.getAccessFlags().isSynthetic() && mth.getAccessFlags().isStatic()) {
if (mth.getBasicBlocks().size() == 1) {
BlockNode block = mth.getBasicBlocks().get(0);
// synthetic field getter
if (block.getInstructions().size() == 1) {
InsnNode insn = block.getInstructions().get(0);
if (insn.getType() == InsnType.RETURN) {
InsnNode inl = new InsnNode(InsnType.ARGS, 1);
inl.addArg(insn.getArg(0));
addInlineAttr(mth, inl);
return;
}
}
// synthetic field setter
if (block.getInstructions().size() == 2) {
if (block.getInstructions().get(1).getType() == InsnType.RETURN) {
InsnNode insn = block.getInstructions().get(0);
addInlineAttr(mth, insn);
return;
}
AccessInfo accessFlags = mth.getAccessFlags();
if (accessFlags.isSynthetic() && accessFlags.isStatic()) {
if (mth.getBasicBlocks().size() == 2) {
BlockNode block = mth.getBasicBlocks().get(1);
if (block.getAttributes().contains(AttributeFlag.RETURN)) {
inlineMth(mth);
}
}
}
}
// synthetic method invoke
if (block.getInstructions().size() == 1) {
InsnNode insn = block.getInstructions().get(0);
addInlineAttr(mth, insn);
}
private static void inlineMth(MethodNode mth) {
BlockNode firstBlock = mth.getBasicBlocks().get(0);
if (firstBlock.getInstructions().isEmpty()) {
// synthetic field getter
BlockNode block = mth.getBasicBlocks().get(1);
InsnNode insn = block.getInstructions().get(0);
InsnNode inl = new InsnNode(InsnType.ARGS, 1);
inl.addArg(insn.getArg(0));
addInlineAttr(mth, inl);
} else {
// synthetic field setter or method invoke
if (firstBlock.getInstructions().size() == 1) {
addInlineAttr(mth, firstBlock.getInstructions().get(0));
}
}
}
......@@ -50,5 +47,4 @@ public class MethodInlinerVisitor extends AbstractVisitor {
mth.getAttributes().add(attr);
mth.getAttributes().add(AttributeFlag.DONT_GENERATE);
}
}
......@@ -10,6 +10,12 @@ public abstract class AbstractTest {
}
}
public static void assertTrue(boolean condition, String msg) {
if (!condition) {
throw new AssertionError(msg);
}
}
public static void assertEquals(int a1, int a2) {
if (a1 != a2) {
throw new AssertionError(a1 + " != " + a2);
......
package jadx.samples;
import java.lang.reflect.Method;
public class TestInner2 extends AbstractTest {
private String a;
......@@ -26,12 +28,56 @@ public class TestInner2 extends AbstractTest {
}
}
private String c;
private void setC(String c) {
this.c = c;
}
public class C {
public String c() {
setC("c");
return c;
}
}
private static String d;
private static void setD(String s) {
d = s;
}
public static class D {
public String d() {
setD("d");
return d;
}
}
// value from java.lang.reflect.Modifier
static final int SYNTHETIC = 0x00001000;
@Override
public boolean testRun() throws Exception {
assertTrue((new A()).a().equals("a"));
assertTrue(a.equals("a"));
assertTrue((new B()).b().equals("b"));
assertTrue(b.equals("b"));
assertTrue((new C()).c().equals("c"));
assertTrue(c.equals("c"));
assertTrue((new D()).d().equals("d"));
assertTrue(d.equals("d"));
Method[] mths = TestInner2.class.getDeclaredMethods();
for (Method mth : mths) {
if(mth.getName().startsWith("access$")) {
int modifiers = mth.getModifiers();
assertTrue((modifiers & SYNTHETIC) != 0, "Synthetic methods must be removed");
}
}
return true;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment