use of jadx.core.dex.nodes.FieldNode in project jadx by skylot.
the class ExtractFieldInit method processFieldsDependencies.
private static List<FieldNode> processFieldsDependencies(ClassNode cls, List<FieldInitInfo> inits) {
List<FieldNode> orderedFields = Utils.collectionMap(inits, v -> v.fieldNode);
// collect dependant fields
Map<FieldNode, List<FieldNode>> deps = new HashMap<>(inits.size());
for (FieldInitInfo initInfo : inits) {
IndexInsnNode insn = initInfo.putInsn;
boolean staticField = insn.getType() == InsnType.SPUT;
InsnType useType = staticField ? InsnType.SGET : InsnType.IGET;
insn.visitInsns(subInsn -> {
if (subInsn.getType() == useType) {
FieldInfo fieldInfo = (FieldInfo) ((IndexInsnNode) subInsn).getIndex();
if (fieldInfo.getDeclClass().equals(cls.getClassInfo())) {
FieldNode depField = cls.searchField(fieldInfo);
if (depField != null) {
deps.computeIfAbsent(initInfo.fieldNode, k -> new ArrayList<>()).add(depField);
}
}
}
});
}
if (deps.isEmpty()) {
return orderedFields;
}
// build new list with deps fields before usage field
List<FieldNode> result = new ArrayList<>();
for (FieldNode field : orderedFields) {
int idx = result.indexOf(field);
List<FieldNode> fieldDeps = deps.get(field);
if (fieldDeps == null) {
if (idx == -1) {
result.add(field);
}
continue;
}
if (idx == -1) {
for (FieldNode depField : fieldDeps) {
if (!result.contains(depField)) {
result.add(depField);
}
}
result.add(field);
continue;
}
for (FieldNode depField : fieldDeps) {
int depIdx = result.indexOf(depField);
if (depIdx == -1) {
result.add(idx, depField);
} else if (depIdx > idx) {
result.remove(depIdx);
result.add(idx, depField);
}
}
}
return result;
}
use of jadx.core.dex.nodes.FieldNode in project jadx by skylot.
the class JadxDecompiler method convertNode.
@Nullable
JavaNode convertNode(Object obj) {
if (obj instanceof VarRef) {
VarRef varRef = (VarRef) obj;
MethodNode mthNode = varRef.getMth();
JavaMethod mth = getJavaMethodByNode(mthNode);
if (mth == null) {
return null;
}
return new JavaVariable(mth, varRef);
}
if (!(obj instanceof LineAttrNode)) {
return null;
}
LineAttrNode node = (LineAttrNode) obj;
if (node.contains(AFlag.DONT_GENERATE)) {
return null;
}
if (obj instanceof ClassNode) {
return convertClassNode((ClassNode) obj);
}
if (obj instanceof MethodNode) {
return getJavaMethodByNode(((MethodNode) obj));
}
if (obj instanceof FieldNode) {
return getJavaFieldByNode((FieldNode) obj);
}
throw new JadxRuntimeException("Unexpected node type: " + obj);
}
use of jadx.core.dex.nodes.FieldNode in project jadx by skylot.
the class ResTableParser method getResName.
private String getResName(String typeName, int resRef, String origKeyName) {
if (this.useRawResName) {
return origKeyName;
}
String renamedKey = resStorage.getRename(resRef);
if (renamedKey != null) {
return renamedKey;
}
FieldNode constField = root.getConstValues().getGlobalConstFields().get(resRef);
if (constField != null) {
constField.add(AFlag.DONT_RENAME);
return constField.getName();
}
// styles might contain dots in name, use VALID_RES_KEY_PATTERN only for resource file name
if (typeName.equals("style")) {
return origKeyName;
} else if (VALID_RES_KEY_PATTERN.matcher(origKeyName).matches()) {
return origKeyName;
}
// Making sure origKeyName compliant with resource file name rules
Matcher m = VALID_RES_KEY_PATTERN.matcher(origKeyName);
StringBuilder sb = new StringBuilder();
boolean first = true;
while (m.find()) {
if (!first) {
sb.append("_");
}
sb.append(m.group());
first = false;
}
// autogenerate key name, appended with cleaned origKeyName to be human-friendly
String newResName = String.format("res_0x%08x", resRef);
String cleanedResName = sb.toString();
if (!cleanedResName.isEmpty()) {
newResName += "_" + cleanedResName.toLowerCase();
}
return newResName;
}
use of jadx.core.dex.nodes.FieldNode in project jadx by skylot.
the class ClassModifier method processAnonymousConstructor.
/**
* Remove super call and put into removed fields from anonymous constructor
*/
private static void processAnonymousConstructor(MethodNode mth) {
if (!mth.contains(AFlag.ANONYMOUS_CONSTRUCTOR)) {
return;
}
List<InsnNode> usedInsns = new ArrayList<>();
Map<InsnArg, FieldNode> argsMap = getArgsToFieldsMapping(mth, usedInsns);
for (Map.Entry<InsnArg, FieldNode> entry : argsMap.entrySet()) {
FieldNode field = entry.getValue();
if (field == null) {
continue;
}
InsnArg arg = entry.getKey();
field.addAttr(new FieldReplaceAttr(arg));
field.add(AFlag.DONT_GENERATE);
if (arg.isRegister()) {
arg.add(AFlag.SKIP_ARG);
SkipMethodArgsAttr.skipArg(mth, ((RegisterArg) arg));
}
}
for (InsnNode usedInsn : usedInsns) {
usedInsn.add(AFlag.DONT_GENERATE);
}
}
use of jadx.core.dex.nodes.FieldNode in project jadx by skylot.
the class EnumVisitor method processEnumFieldByRegister.
@Nullable
private EnumField processEnumFieldByRegister(ClassNode cls, RegisterArg arg, BlockNode staticBlock, List<InsnNode> toRemove) {
InsnNode assignInsn = arg.getAssignInsn();
if (assignInsn != null && assignInsn.getType() == InsnType.SGET) {
return processEnumFieldByField(cls, assignInsn, staticBlock, toRemove);
}
SSAVar ssaVar = arg.getSVar();
if (ssaVar.getUseCount() == 0) {
return null;
}
InsnNode constrInsn = ssaVar.getAssign().getParentInsn();
if (constrInsn == null || constrInsn.getType() != InsnType.CONSTRUCTOR) {
return null;
}
FieldNode enumFieldNode = searchEnumField(cls, ssaVar, toRemove);
if (enumFieldNode == null) {
enumFieldNode = createFakeField(cls, "EF" + arg.getRegNum());
cls.addField(enumFieldNode);
}
return createEnumFieldByConstructor(cls, enumFieldNode, (ConstructorInsn) constrInsn);
}
Aggregations