Commit 5de4d079 authored by sergey-wowwow's avatar sergey-wowwow Committed by skylot

fix: generates code of missing R class (#353)

parent 8c43e7f7
......@@ -91,7 +91,6 @@ public final class JadxDecompiler {
root.initClassPath();
root.loadResources(getResources());
root.initAppResClass();
initVisitors();
}
......
......@@ -94,10 +94,7 @@ public class RootNode {
ResourceStorage resStorage = parser.getResStorage();
constValues.setResourcesNames(resStorage.getResourcesNames());
appPackage = resStorage.getAppPackage();
}
public void initAppResClass() {
appResClass = AndroidResourcesUtils.searchAppResClass(this);
appResClass = AndroidResourcesUtils.searchAppResClass(this, resStorage);
}
public void initClassPath() {
......
package jadx.core.utils.android;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -11,6 +16,8 @@ import jadx.core.dex.info.ClassInfo;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.DexNode;
import jadx.core.dex.nodes.RootNode;
import jadx.core.xmlgen.ResourceStorage;
import jadx.core.xmlgen.entry.ResourceEntry;
/**
* Android resources specific handlers
......@@ -21,7 +28,7 @@ public class AndroidResourcesUtils {
private AndroidResourcesUtils() {
}
public static ClassNode searchAppResClass(RootNode root) {
public static ClassNode searchAppResClass(RootNode root, ResourceStorage resStorage) {
String appPackage = root.getAppPackage();
String fullName = appPackage != null ? appPackage + ".R" : "R";
ClassNode resCls = root.searchClassByName(fullName);
......@@ -36,7 +43,7 @@ public class AndroidResourcesUtils {
LOG.info("Found several 'R' class candidates: {}", candidates);
}
LOG.warn("Unknown 'R' class, create references to '{}'", fullName);
return makeClass(root, fullName);
return makeClass(root, fullName, resStorage);
}
public static boolean handleAppResField(CodeWriter code, ClassGen clsGen, ClassInfo declClass) {
......@@ -50,12 +57,48 @@ public class AndroidResourcesUtils {
return false;
}
private static ClassNode makeClass(RootNode root, String clsName) {
private static ClassNode makeClass(RootNode root, String clsName, ResourceStorage resStorage) {
List<DexNode> dexNodes = root.getDexNodes();
if (dexNodes.isEmpty()) {
return null;
}
ClassInfo r = ClassInfo.fromName(root, clsName);
return new ClassNode(dexNodes.get(0), r);
ClassNode classNode = new ClassNode(dexNodes.get(0), r);
generateMissingRCode(classNode, resStorage);
return classNode;
}
private static void generateMissingRCode(ClassNode cls, ResourceStorage resStorage) {
Map<String, List<ResourceEntry>> sortedMap = new HashMap<>();
for(ResourceEntry ri : resStorage.getResources()) {
List<ResourceEntry> entries = sortedMap.get(ri.getTypeName());
if(entries == null) {
entries = new LinkedList<>();
sortedMap.put(ri.getTypeName(), entries);
}
entries.add(ri);
}
Set<String> addedValues = new HashSet<>();
CodeWriter clsCode = new CodeWriter();
if (!"".equals(cls.getPackage())) {
clsCode.add("package ").add(cls.getPackage()).add(';').newLine();
}
clsCode.startLine("public final class ").add(cls.getShortName()).add(" {").incIndent();
for(String typeName : sortedMap.keySet()) {
clsCode.startLine("public static final class ").add(typeName).add(" {").incIndent();
for(ResourceEntry ri : sortedMap.get(typeName)) {
if(addedValues.add(ri.getTypeName() + "." + ri.getKeyName())) {
clsCode.startLine("public static final int ").add(ri.getKeyName()).add(" = ")
.add("" + ri.getId()).add(";");
}
}
clsCode.decIndent();
clsCode.add("}");
}
clsCode.decIndent();
clsCode.add("}");
cls.setCode(clsCode);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment