fix: invoke in nested anonymous classes (#1305)
This commit is contained in:
@@ -763,8 +763,7 @@ public class InsnGen {
|
||||
case VIRTUAL:
|
||||
case INTERFACE:
|
||||
InsnArg arg = insn.getArg(0);
|
||||
// FIXME: add 'this' for equals methods in scope
|
||||
if (!arg.isThis()) {
|
||||
if (needInvokeArg(arg)) {
|
||||
addArgDot(code, arg);
|
||||
}
|
||||
k++;
|
||||
@@ -799,6 +798,20 @@ public class InsnGen {
|
||||
generateMethodArguments(code, insn, k, callMthNode);
|
||||
}
|
||||
|
||||
// FIXME: add 'this' for equals methods in scope
|
||||
private boolean needInvokeArg(InsnArg arg) {
|
||||
if (arg.isAnyThis()) {
|
||||
if (arg.isThis()) {
|
||||
return false;
|
||||
}
|
||||
ClassNode clsNode = mth.root().resolveClass(arg.getType());
|
||||
if (clsNode != null && clsNode.contains(AFlag.DONT_GENERATE)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void makeInvokeLambda(ICodeWriter code, InvokeCustomNode customNode) throws CodegenException {
|
||||
if (customNode.isUseRef()) {
|
||||
makeRefLambda(code, customNode);
|
||||
|
||||
@@ -232,6 +232,27 @@ public abstract class InsnArg extends Typed {
|
||||
return contains(AFlag.THIS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true for 'this' from other classes (often occur in anonymous classes)
|
||||
*/
|
||||
public boolean isAnyThis() {
|
||||
if (contains(AFlag.THIS)) {
|
||||
return true;
|
||||
}
|
||||
InsnNode wrappedInsn = unwrap();
|
||||
if (wrappedInsn != null && wrappedInsn.getType() == InsnType.IGET) {
|
||||
return wrappedInsn.getArg(0).isAnyThis();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public InsnNode unwrap() {
|
||||
if (isInsnWrap()) {
|
||||
return ((InsnWrapArg) this).getWrapInsn();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isConst() {
|
||||
return isLiteral() || (isInsnWrap() && ((InsnWrapArg) this).getWrapInsn().isConstInsn());
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ public class RenameVisitor extends AbstractVisitor {
|
||||
// check inner classes names
|
||||
ClassInfo parentClass = classInfo.getParentClass();
|
||||
while (parentClass != null) {
|
||||
if (parentClass.getAliasShortName().equals(clsName)) {
|
||||
if (parentClass.getAliasShortName().equals(newShortName)) {
|
||||
String clsAlias = deobfuscator.getClsAlias(cls);
|
||||
classInfo.changeShortName(clsAlias);
|
||||
cls.addAttr(new RenameReasonAttr(cls).append("collision with other inner class name"));
|
||||
|
||||
@@ -74,6 +74,13 @@ public class JadxCodeAssertions extends AbstractStringAssert<JadxCodeAssertions>
|
||||
return newCode;
|
||||
}
|
||||
|
||||
public JadxCodeAssertions removeLineComments() {
|
||||
String code = actual.replaceAll("//.*(?!$)", "");
|
||||
JadxCodeAssertions newCode = new JadxCodeAssertions(code);
|
||||
newCode.print();
|
||||
return newCode;
|
||||
}
|
||||
|
||||
public JadxCodeAssertions print() {
|
||||
System.out.println("-----------------------------------------------------------");
|
||||
System.out.println(actual);
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package jadx.tests.integration.inner;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jadx.api.CommentsLevel;
|
||||
import jadx.tests.api.IntegrationTest;
|
||||
|
||||
import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;
|
||||
|
||||
public class TestAnonymousClass18 extends IntegrationTest {
|
||||
|
||||
@SuppressWarnings({ "Convert2Lambda", "Anonymous2MethodRef", "unused" })
|
||||
public static class TestCls {
|
||||
|
||||
public interface Job {
|
||||
void executeJob();
|
||||
}
|
||||
|
||||
public void start() {
|
||||
runJob(new Job() {
|
||||
@Override
|
||||
public void executeJob() {
|
||||
runJob(new Job() {
|
||||
@Override
|
||||
public void executeJob() {
|
||||
doSomething();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void doSomething() {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void runJob(Job job) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
getArgs().setCommentsLevel(CommentsLevel.WARN);
|
||||
assertThat(getClassNode(TestCls.class))
|
||||
.code()
|
||||
.doesNotContain("AnonymousClass1.this")
|
||||
.doesNotContain("class AnonymousClass1")
|
||||
// .doesNotContain("TestAnonymousClass18$TestCls.runJob(") // TODO: ???
|
||||
.containsOne(indent() + "doSomething();");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoInline() {
|
||||
getArgs().setInlineAnonymousClasses(false);
|
||||
assertThat(getClassNode(TestCls.class))
|
||||
.code()
|
||||
.containsOne("class AnonymousClass1 implements Job {")
|
||||
.containsOne("class C00001 implements Job {")
|
||||
.containsOne("AnonymousClass1.this.doSomething();");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user