core: skip synthetic arguments in anonymous class constructor
This commit is contained in:
@@ -647,6 +647,10 @@ public class InsnGen {
|
||||
if (arg.contains(AFlag.SKIP_ARG)) {
|
||||
continue;
|
||||
}
|
||||
RegisterArg callArg = getCallMthArg(callMth, i - startArgNum);
|
||||
if (callArg != null && callArg.contains(AFlag.SKIP_ARG)) {
|
||||
continue;
|
||||
}
|
||||
if (i != k) {
|
||||
code.add(", ");
|
||||
}
|
||||
@@ -660,6 +664,17 @@ public class InsnGen {
|
||||
code.add(')');
|
||||
}
|
||||
|
||||
private static RegisterArg getCallMthArg(@Nullable MethodNode callMth, int num) {
|
||||
if (callMth == null) {
|
||||
return null;
|
||||
}
|
||||
List<RegisterArg> args = callMth.getArguments(false);
|
||||
if (args != null && num < args.size()) {
|
||||
return args.get(num);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add additional cast for overloaded method argument.
|
||||
*/
|
||||
|
||||
@@ -11,6 +11,7 @@ import jadx.core.dex.instructions.IndexInsnNode;
|
||||
import jadx.core.dex.instructions.InsnType;
|
||||
import jadx.core.dex.instructions.args.InsnArg;
|
||||
import jadx.core.dex.instructions.args.RegisterArg;
|
||||
import jadx.core.dex.instructions.args.SSAVar;
|
||||
import jadx.core.dex.instructions.mods.ConstructorInsn;
|
||||
import jadx.core.dex.nodes.BlockNode;
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
@@ -135,13 +136,24 @@ public class ClassModifier extends AbstractVisitor {
|
||||
mth.add(AFlag.DONT_GENERATE);
|
||||
continue;
|
||||
}
|
||||
// remove synthetic constructor for inner non-static classes
|
||||
// remove synthetic constructor for inner classes
|
||||
if (af.isSynthetic() && af.isConstructor() && mth.getBasicBlocks().size() == 2) {
|
||||
List<InsnNode> insns = mth.getBasicBlocks().get(0).getInstructions();
|
||||
if (insns.size() == 1 && insns.get(0).getType() == InsnType.CONSTRUCTOR) {
|
||||
ConstructorInsn constr = (ConstructorInsn) insns.get(0);
|
||||
if (constr.isThis() && !mth.getArguments(false).isEmpty()) {
|
||||
mth.removeFirstArgument();
|
||||
List<RegisterArg> args = mth.getArguments(false);
|
||||
if (constr.isThis() && !args.isEmpty()) {
|
||||
// remove first arg for non-static class (references to outer class)
|
||||
if (args.get(0).getType().equals(cls.getParentClass().getClassInfo().getType())) {
|
||||
args.get(0).add(AFlag.SKIP_ARG);
|
||||
}
|
||||
// remove unused args
|
||||
for (RegisterArg arg : args) {
|
||||
SSAVar sVar = arg.getSVar();
|
||||
if (sVar != null && sVar.getUseCount() == 0) {
|
||||
arg.add(AFlag.SKIP_ARG);
|
||||
}
|
||||
}
|
||||
mth.add(AFlag.DONT_GENERATE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package jadx.tests.integration.invoke;
|
||||
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
import jadx.tests.api.IntegrationTest;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static jadx.tests.api.utils.JadxMatchers.containsOne;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class TestInvoke1 extends IntegrationTest {
|
||||
|
||||
public static class TestCls {
|
||||
|
||||
private A is;
|
||||
|
||||
private C test(int start) throws IOException {
|
||||
int id = is.readInt32();
|
||||
String name = is.readString16Fixed(128);
|
||||
|
||||
long typeStringsOffset = start + is.readInt32();
|
||||
long keyStringsOffset = start + is.readInt32();
|
||||
|
||||
String[] types = null;
|
||||
if (typeStringsOffset != 0) {
|
||||
types = strs();
|
||||
}
|
||||
String[] keys = null;
|
||||
if (keyStringsOffset != 0) {
|
||||
keys = strs();
|
||||
}
|
||||
|
||||
C pkg = new C(id, name, types, keys);
|
||||
if (id == 0x7F) {
|
||||
is.readInt32();
|
||||
}
|
||||
return pkg;
|
||||
}
|
||||
|
||||
private String[] strs() {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
private static final class C {
|
||||
public C(int id, String name, String[] types, String[] keys) {
|
||||
}
|
||||
}
|
||||
|
||||
private final class A {
|
||||
public int readInt32() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public String readString16Fixed(int i) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
ClassNode cls = getClassNode(TestCls.class);
|
||||
String code = cls.getCode().toString();
|
||||
|
||||
assertThat(code, containsOne("C pkg = new C(id, name, types, keys);"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user