fix: allow to regenerate class code (#791)
This commit is contained in:
@@ -40,7 +40,7 @@ import jadx.core.utils.exceptions.DecodeException;
|
||||
import jadx.core.utils.exceptions.JadxRuntimeException;
|
||||
|
||||
import static jadx.core.dex.nodes.ProcessState.LOADED;
|
||||
import static jadx.core.dex.nodes.ProcessState.UNLOADED;
|
||||
import static jadx.core.dex.nodes.ProcessState.NOT_LOADED;
|
||||
|
||||
public class ClassNode extends LineAttrNode implements ILoadable, ICodeNode {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ClassNode.class);
|
||||
@@ -262,23 +262,33 @@ public class ClassNode extends LineAttrNode implements ILoadable, ICodeNode {
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized ICodeInfo decompile() {
|
||||
public ICodeInfo decompile() {
|
||||
return decompile(true);
|
||||
}
|
||||
|
||||
public ICodeInfo getCode() {
|
||||
return decompile(true);
|
||||
}
|
||||
|
||||
public ICodeInfo reloadCode() {
|
||||
return decompile(false);
|
||||
}
|
||||
|
||||
private synchronized ICodeInfo decompile(boolean searchInCache) {
|
||||
ICodeCache codeCache = root().getCodeCache();
|
||||
ClassNode topParentClass = getTopParentClass();
|
||||
String clsRawName = topParentClass.getRawName();
|
||||
ICodeInfo code = codeCache.get(clsRawName);
|
||||
if (code != null) {
|
||||
return code;
|
||||
if (searchInCache) {
|
||||
ICodeInfo code = codeCache.get(clsRawName);
|
||||
if (code != null) {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
ICodeInfo codeInfo = ProcessClass.generateCode(topParentClass);
|
||||
codeCache.add(clsRawName, codeInfo);
|
||||
return codeInfo;
|
||||
}
|
||||
|
||||
public ICodeInfo getCode() {
|
||||
return decompile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
for (MethodNode mth : getMethods()) {
|
||||
@@ -300,7 +310,7 @@ public class ClassNode extends LineAttrNode implements ILoadable, ICodeNode {
|
||||
innerClasses.forEach(ClassNode::unload);
|
||||
fields.forEach(FieldNode::unloadAttributes);
|
||||
unloadAttributes();
|
||||
setState(UNLOADED);
|
||||
setState(NOT_LOADED);
|
||||
}
|
||||
|
||||
private void buildCache() {
|
||||
|
||||
@@ -4,15 +4,13 @@ public enum ProcessState {
|
||||
NOT_LOADED,
|
||||
LOADED,
|
||||
PROCESS_STARTED,
|
||||
PROCESS_COMPLETE,
|
||||
GENERATED,
|
||||
UNLOADED;
|
||||
PROCESS_COMPLETE;
|
||||
|
||||
public boolean isLoaded() {
|
||||
return this != NOT_LOADED;
|
||||
}
|
||||
|
||||
public boolean isProcessed() {
|
||||
return this == PROCESS_COMPLETE || this == GENERATED || this == UNLOADED;
|
||||
return this == PROCESS_COMPLETE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,4 +51,11 @@ public class JadxCodeAssertions extends AbstractStringAssert<JadxCodeAssertions>
|
||||
}
|
||||
return countString(1, sb.toString());
|
||||
}
|
||||
|
||||
public JadxCodeAssertions print() {
|
||||
System.out.println("-----------------------------------------------------------");
|
||||
System.out.println(actual);
|
||||
System.out.println("-----------------------------------------------------------");
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package jadx.tests.integration.others;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
import jadx.tests.api.IntegrationTest;
|
||||
|
||||
import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;
|
||||
|
||||
public class TestClassReGen extends IntegrationTest {
|
||||
|
||||
public static class TestCls {
|
||||
private int intField = 5;
|
||||
|
||||
public static class A {
|
||||
}
|
||||
|
||||
public int test() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
ClassNode cls = getClassNode(TestCls.class);
|
||||
assertThat(cls.getCode())
|
||||
.containsOnlyOnce("private int intField = 5;")
|
||||
.containsOnlyOnce("public static class A {")
|
||||
.containsOnlyOnce("public int test() {");
|
||||
|
||||
cls.getInnerClasses().get(0).getClassInfo().changeShortName("ARenamed");
|
||||
cls.searchMethodByShortName("test").getMethodInfo().setAlias("testRenamed");
|
||||
cls.searchFieldByName("intField").getFieldInfo().setAlias("intFieldRenamed");
|
||||
|
||||
assertThat(cls.reloadCode())
|
||||
.print()
|
||||
.containsOnlyOnce("private int intFieldRenamed = 5;")
|
||||
.containsOnlyOnce("public static class ARenamed {")
|
||||
.containsOnlyOnce("public int testRenamed() {");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user