Skip to content

Commit

Permalink
fix: allow to regenerate class code (#791)
Browse files Browse the repository at this point in the history
  • Loading branch information
skylot committed Dec 13, 2019
1 parent ef5da49 commit 1c6e51f
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 14 deletions.
30 changes: 20 additions & 10 deletions jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
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);
Expand Down Expand Up @@ -262,23 +262,33 @@ public void ensureProcessed() {
}
}

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()) {
Expand All @@ -300,7 +310,7 @@ public void unload() {
innerClasses.forEach(ClassNode::unload);
fields.forEach(FieldNode::unloadAttributes);
unloadAttributes();
setState(UNLOADED);
setState(NOT_LOADED);
}

private void buildCache() {
Expand Down
6 changes: 2 additions & 4 deletions jadx-core/src/main/java/jadx/core/dex/nodes/ProcessState.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,11 @@ public JadxCodeAssertions containsLines(int commonIndent, String... lines) {
}
return countString(1, sb.toString());
}

public JadxCodeAssertions print() {
System.out.println("-----------------------------------------------------------");
System.out.println(actual);
System.out.println("-----------------------------------------------------------");
return this;
}
}
Original file line number Diff line number Diff line change
@@ -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() {");
}
}

0 comments on commit 1c6e51f

Please sign in to comment.