Fix sythetic methods inline
This commit is contained in:
@@ -3,6 +3,7 @@ package jadx.dex.visitors;
|
|||||||
import jadx.dex.attributes.AttributeFlag;
|
import jadx.dex.attributes.AttributeFlag;
|
||||||
import jadx.dex.attributes.IAttribute;
|
import jadx.dex.attributes.IAttribute;
|
||||||
import jadx.dex.attributes.MethodInlineAttr;
|
import jadx.dex.attributes.MethodInlineAttr;
|
||||||
|
import jadx.dex.info.AccessInfo;
|
||||||
import jadx.dex.instructions.InsnType;
|
import jadx.dex.instructions.InsnType;
|
||||||
import jadx.dex.nodes.BlockNode;
|
import jadx.dex.nodes.BlockNode;
|
||||||
import jadx.dex.nodes.InsnNode;
|
import jadx.dex.nodes.InsnNode;
|
||||||
@@ -13,34 +14,30 @@ public class MethodInlinerVisitor extends AbstractVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(MethodNode mth) throws JadxException {
|
public void visit(MethodNode mth) throws JadxException {
|
||||||
if (mth.getAccessFlags().isSynthetic() && mth.getAccessFlags().isStatic()) {
|
AccessInfo accessFlags = mth.getAccessFlags();
|
||||||
if (mth.getBasicBlocks().size() == 1) {
|
if (accessFlags.isSynthetic() && accessFlags.isStatic()) {
|
||||||
BlockNode block = mth.getBasicBlocks().get(0);
|
if (mth.getBasicBlocks().size() == 2) {
|
||||||
// synthetic field getter
|
BlockNode block = mth.getBasicBlocks().get(1);
|
||||||
if (block.getInstructions().size() == 1) {
|
if (block.getAttributes().contains(AttributeFlag.RETURN)) {
|
||||||
InsnNode insn = block.getInstructions().get(0);
|
inlineMth(mth);
|
||||||
if (insn.getType() == InsnType.RETURN) {
|
|
||||||
InsnNode inl = new InsnNode(InsnType.ARGS, 1);
|
|
||||||
inl.addArg(insn.getArg(0));
|
|
||||||
addInlineAttr(mth, inl);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// synthetic field setter
|
private static void inlineMth(MethodNode mth) {
|
||||||
if (block.getInstructions().size() == 2) {
|
BlockNode firstBlock = mth.getBasicBlocks().get(0);
|
||||||
if (block.getInstructions().get(1).getType() == InsnType.RETURN) {
|
if (firstBlock.getInstructions().isEmpty()) {
|
||||||
InsnNode insn = block.getInstructions().get(0);
|
// synthetic field getter
|
||||||
addInlineAttr(mth, insn);
|
BlockNode block = mth.getBasicBlocks().get(1);
|
||||||
return;
|
InsnNode insn = block.getInstructions().get(0);
|
||||||
}
|
InsnNode inl = new InsnNode(InsnType.ARGS, 1);
|
||||||
}
|
inl.addArg(insn.getArg(0));
|
||||||
|
addInlineAttr(mth, inl);
|
||||||
// synthetic method invoke
|
} else {
|
||||||
if (block.getInstructions().size() == 1) {
|
// synthetic field setter or method invoke
|
||||||
InsnNode insn = block.getInstructions().get(0);
|
if (firstBlock.getInstructions().size() == 1) {
|
||||||
addInlineAttr(mth, insn);
|
addInlineAttr(mth, firstBlock.getInstructions().get(0));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -50,5 +47,4 @@ public class MethodInlinerVisitor extends AbstractVisitor {
|
|||||||
mth.getAttributes().add(attr);
|
mth.getAttributes().add(attr);
|
||||||
mth.getAttributes().add(AttributeFlag.DONT_GENERATE);
|
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) {
|
public static void assertEquals(int a1, int a2) {
|
||||||
if (a1 != a2) {
|
if (a1 != a2) {
|
||||||
throw new AssertionError(a1 + " != " + a2);
|
throw new AssertionError(a1 + " != " + a2);
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package jadx.samples;
|
package jadx.samples;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
public class TestInner2 extends AbstractTest {
|
public class TestInner2 extends AbstractTest {
|
||||||
|
|
||||||
private String a;
|
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
|
@Override
|
||||||
public boolean testRun() throws Exception {
|
public boolean testRun() throws Exception {
|
||||||
assertTrue((new A()).a().equals("a"));
|
assertTrue((new A()).a().equals("a"));
|
||||||
assertTrue(a.equals("a"));
|
assertTrue(a.equals("a"));
|
||||||
|
|
||||||
assertTrue((new B()).b().equals("b"));
|
assertTrue((new B()).b().equals("b"));
|
||||||
assertTrue(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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user