use of com.googlecode.d2j.node.DexFieldNode in project dex2jar by pxb1988.
the class DexFix method fixStaticFinalFieldValue.
/**
* init value to default if the field is static and final, and the field is not init in clinit method
*
* erase the default value if the field is init in clinit method
*
* @param classNode
*/
public static void fixStaticFinalFieldValue(final DexClassNode classNode) {
if (classNode.fields == null) {
return;
}
final Map<String, DexFieldNode> fs = new HashMap<>();
final Map<String, DexFieldNode> shouldNotBeAssigned = new HashMap<>();
for (DexFieldNode fn : classNode.fields) {
if ((fn.access & ACC_STATIC_FINAL) == ACC_STATIC_FINAL) {
if (fn.cst == null) {
char t = fn.field.getType().charAt(0);
if (t == 'L' || t == '[') {
// ignore Object
continue;
}
fs.put(fn.field.getName() + ":" + fn.field.getType(), fn);
} else if (isPrimitiveZero(fn.field.getType(), fn.cst)) {
shouldNotBeAssigned.put(fn.field.getName() + ":" + fn.field.getType(), fn);
}
}
}
if (fs.isEmpty() && shouldNotBeAssigned.isEmpty()) {
return;
}
DexMethodNode node = null;
if (classNode.methods != null) {
for (DexMethodNode mn : classNode.methods) {
if (mn.method.getName().equals("<clinit>")) {
node = mn;
break;
}
}
}
if (node != null) {
if (node.codeNode != null) {
node.codeNode.accept(new DexCodeVisitor() {
@Override
public void visitFieldStmt(Op op, int a, int b, Field field) {
switch(op) {
case SPUT:
case SPUT_BOOLEAN:
case SPUT_BYTE:
case SPUT_CHAR:
case SPUT_OBJECT:
case SPUT_SHORT:
case SPUT_WIDE:
if (field.getOwner().equals(classNode.className)) {
String key = field.getName() + ":" + field.getType();
fs.remove(key);
DexFieldNode dn = shouldNotBeAssigned.get(key);
if (dn != null) {
//System.out.println(field.getName() + ":" + field.getType());
dn.cst = null;
}
}
break;
default:
// ignored
break;
}
}
});
} else {
// has init but no code
return;
}
}
for (DexFieldNode fn : fs.values()) {
fn.cst = getDefaultValueOfType(fn.field.getType().charAt(0));
}
}
Aggregations