refactor: split field init attribute
This commit is contained in:
@@ -22,8 +22,7 @@ import jadx.core.Consts;
|
||||
import jadx.core.dex.attributes.AFlag;
|
||||
import jadx.core.dex.attributes.AType;
|
||||
import jadx.core.dex.attributes.AttrNode;
|
||||
import jadx.core.dex.attributes.FieldInitAttr;
|
||||
import jadx.core.dex.attributes.FieldInitAttr.InitType;
|
||||
import jadx.core.dex.attributes.fldinit.FieldInitAttr;
|
||||
import jadx.core.dex.attributes.nodes.EnumClassAttr;
|
||||
import jadx.core.dex.attributes.nodes.EnumClassAttr.EnumField;
|
||||
import jadx.core.dex.attributes.nodes.JadxError;
|
||||
@@ -395,14 +394,14 @@ public class ClassGen {
|
||||
FieldInitAttr fv = f.get(AType.FIELD_INIT);
|
||||
if (fv != null) {
|
||||
code.add(" = ");
|
||||
if (fv.getValueType() == InitType.CONST) {
|
||||
if (fv.isConst()) {
|
||||
EncodedValue encodedValue = fv.getEncodedValue();
|
||||
if (encodedValue.getType() == EncodedType.ENCODED_NULL) {
|
||||
code.add(TypeGen.literalToString(0, f.getType(), cls, fallback));
|
||||
} else {
|
||||
annotationGen.encodeValue(cls.root(), code, encodedValue);
|
||||
}
|
||||
} else if (fv.getValueType() == InitType.INSN) {
|
||||
} else if (fv.isInsn()) {
|
||||
InsnGen insnGen = makeInsnGen(fv.getInsnMth());
|
||||
addInsnBody(insnGen, code, fv.getInsn());
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import jadx.core.dex.attributes.AFlag;
|
||||
import jadx.core.dex.attributes.AType;
|
||||
import jadx.core.dex.attributes.FieldInitAttr;
|
||||
import jadx.core.dex.attributes.fldinit.FieldInitAttr;
|
||||
import jadx.core.dex.attributes.nodes.DeclareVariablesAttr;
|
||||
import jadx.core.dex.attributes.nodes.ForceReturnAttr;
|
||||
import jadx.core.dex.attributes.nodes.LoopLabelAttr;
|
||||
@@ -287,10 +287,10 @@ public class RegionGen extends InsnGen {
|
||||
staticField(code, fn.getFieldInfo());
|
||||
// print original value, sometimes replaced with incorrect field
|
||||
FieldInitAttr valueAttr = fn.get(AType.FIELD_INIT);
|
||||
if (valueAttr != null && valueAttr.getValueType() == FieldInitAttr.InitType.CONST) {
|
||||
Object value = valueAttr.getEncodedValue();
|
||||
if (valueAttr != null && valueAttr.isConst()) {
|
||||
Object value = valueAttr.getEncodedValue().getValue();
|
||||
if (value != null) {
|
||||
code.add(" /*").add(value.toString()).add("*/");
|
||||
code.add(" /* ").add(value.toString()).add(" */");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import java.util.Set;
|
||||
|
||||
import jadx.core.dex.attributes.annotations.AnnotationsList;
|
||||
import jadx.core.dex.attributes.annotations.MethodParameters;
|
||||
import jadx.core.dex.attributes.fldinit.FieldInitAttr;
|
||||
import jadx.core.dex.attributes.nodes.DeclareVariablesAttr;
|
||||
import jadx.core.dex.attributes.nodes.EdgeInsnAttr;
|
||||
import jadx.core.dex.attributes.nodes.EnumClassAttr;
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
package jadx.core.dex.attributes;
|
||||
|
||||
import jadx.api.plugins.input.data.annotations.EncodedValue;
|
||||
import jadx.core.dex.nodes.InsnNode;
|
||||
import jadx.core.dex.nodes.MethodNode;
|
||||
|
||||
public class FieldInitAttr implements IAttribute {
|
||||
|
||||
public static final FieldInitAttr NULL_VALUE = constValue(EncodedValue.NULL);
|
||||
|
||||
public enum InitType {
|
||||
CONST,
|
||||
INSN
|
||||
}
|
||||
|
||||
private final Object value;
|
||||
private final InitType valueType;
|
||||
private final MethodNode insnMth;
|
||||
|
||||
private FieldInitAttr(InitType valueType, Object value, MethodNode insnMth) {
|
||||
this.value = value;
|
||||
this.valueType = valueType;
|
||||
this.insnMth = insnMth;
|
||||
}
|
||||
|
||||
public static FieldInitAttr constValue(EncodedValue value) {
|
||||
return new FieldInitAttr(InitType.CONST, value, null);
|
||||
}
|
||||
|
||||
public static FieldInitAttr insnValue(MethodNode mth, InsnNode insn) {
|
||||
return new FieldInitAttr(InitType.INSN, insn, mth);
|
||||
}
|
||||
|
||||
public EncodedValue getEncodedValue() {
|
||||
return (EncodedValue) value;
|
||||
}
|
||||
|
||||
public InsnNode getInsn() {
|
||||
return (InsnNode) value;
|
||||
}
|
||||
|
||||
public InitType getValueType() {
|
||||
return valueType;
|
||||
}
|
||||
|
||||
public MethodNode getInsnMth() {
|
||||
return insnMth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AType<FieldInitAttr> getType() {
|
||||
return AType.FIELD_INIT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "V=" + value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package jadx.core.dex.attributes.fldinit;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import jadx.api.plugins.input.data.annotations.EncodedValue;
|
||||
import jadx.core.dex.attributes.AType;
|
||||
import jadx.core.dex.attributes.IAttribute;
|
||||
import jadx.core.dex.nodes.InsnNode;
|
||||
import jadx.core.dex.nodes.MethodNode;
|
||||
import jadx.core.utils.exceptions.JadxRuntimeException;
|
||||
|
||||
public abstract class FieldInitAttr implements IAttribute {
|
||||
|
||||
public static FieldInitAttr constValue(EncodedValue value) {
|
||||
if (Objects.equals(value, EncodedValue.NULL)) {
|
||||
return FieldInitConstAttr.NULL_VALUE;
|
||||
}
|
||||
return new FieldInitConstAttr(value);
|
||||
}
|
||||
|
||||
public static FieldInitAttr insnValue(MethodNode mth, InsnNode insn) {
|
||||
return new FieldInitInsnAttr(mth, insn);
|
||||
}
|
||||
|
||||
public boolean isConst() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isInsn() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public EncodedValue getEncodedValue() {
|
||||
throw new JadxRuntimeException("Wrong init type");
|
||||
}
|
||||
|
||||
public InsnNode getInsn() {
|
||||
throw new JadxRuntimeException("Wrong init type");
|
||||
}
|
||||
|
||||
public MethodNode getInsnMth() {
|
||||
throw new JadxRuntimeException("Wrong init type");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AType<FieldInitAttr> getType() {
|
||||
return AType.FIELD_INIT;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package jadx.core.dex.attributes.fldinit;
|
||||
|
||||
import jadx.api.plugins.input.data.annotations.EncodedValue;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
public final class FieldInitConstAttr extends FieldInitAttr {
|
||||
public static final FieldInitAttr NULL_VALUE = new FieldInitConstAttr(EncodedValue.NULL);
|
||||
|
||||
private final EncodedValue value;
|
||||
|
||||
FieldInitConstAttr(EncodedValue value) {
|
||||
this.value = requireNonNull(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EncodedValue getEncodedValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConst() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "INIT{" + value + '}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package jadx.core.dex.attributes.fldinit;
|
||||
|
||||
import jadx.core.dex.nodes.InsnNode;
|
||||
import jadx.core.dex.nodes.MethodNode;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
public final class FieldInitInsnAttr extends FieldInitAttr {
|
||||
private final MethodNode mth;
|
||||
private final InsnNode insn;
|
||||
|
||||
FieldInitInsnAttr(MethodNode mth, InsnNode insn) {
|
||||
this.mth = requireNonNull(mth);
|
||||
this.insn = requireNonNull(insn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InsnNode getInsn() {
|
||||
return insn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodNode getInsnMth() {
|
||||
return mth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInsn() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "INIT{" + insn + '}';
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import jadx.api.JadxArgs;
|
||||
import jadx.core.dex.attributes.AType;
|
||||
import jadx.core.dex.attributes.FieldInitAttr;
|
||||
import jadx.core.dex.attributes.fldinit.FieldInitAttr;
|
||||
import jadx.core.dex.instructions.args.LiteralArg;
|
||||
import jadx.core.dex.instructions.args.PrimitiveType;
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
@@ -85,10 +85,7 @@ public class ConstStorage {
|
||||
AccessInfo accFlags = f.getAccessFlags();
|
||||
if (accFlags.isStatic() && accFlags.isFinal()) {
|
||||
FieldInitAttr fv = f.get(AType.FIELD_INIT);
|
||||
if (fv != null
|
||||
&& fv.getValueType() == FieldInitAttr.InitType.CONST
|
||||
&& fv != FieldInitAttr.NULL_VALUE
|
||||
&& fv.getEncodedValue() != null) {
|
||||
if (fv != null && fv.isConst() && fv.getEncodedValue().getValue() != null) {
|
||||
addConstField(cls, f, fv.getEncodedValue().getValue(), accFlags.isPublic());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,8 +23,9 @@ import jadx.api.plugins.input.data.annotations.IAnnotation;
|
||||
import jadx.core.Consts;
|
||||
import jadx.core.ProcessClass;
|
||||
import jadx.core.dex.attributes.AFlag;
|
||||
import jadx.core.dex.attributes.FieldInitAttr;
|
||||
import jadx.core.dex.attributes.annotations.AnnotationsList;
|
||||
import jadx.core.dex.attributes.fldinit.FieldInitAttr;
|
||||
import jadx.core.dex.attributes.fldinit.FieldInitConstAttr;
|
||||
import jadx.core.dex.attributes.nodes.NotificationAttrNode;
|
||||
import jadx.core.dex.attributes.nodes.SourceFileAttr;
|
||||
import jadx.core.dex.info.AccessInfo;
|
||||
@@ -164,7 +165,7 @@ public class ClassNode extends NotificationAttrNode implements ILoadable, ICodeN
|
||||
for (FieldNode f : staticFields) {
|
||||
if (f.getAccessFlags().isFinal()) {
|
||||
// incorrect initialization will be removed if assign found in constructor
|
||||
f.addAttr(FieldInitAttr.NULL_VALUE);
|
||||
f.addAttr(FieldInitConstAttr.NULL_VALUE);
|
||||
}
|
||||
}
|
||||
try {
|
||||
|
||||
@@ -8,7 +8,7 @@ import java.util.Set;
|
||||
|
||||
import jadx.core.dex.attributes.AFlag;
|
||||
import jadx.core.dex.attributes.AType;
|
||||
import jadx.core.dex.attributes.FieldInitAttr;
|
||||
import jadx.core.dex.attributes.fldinit.FieldInitAttr;
|
||||
import jadx.core.dex.info.AccessInfo;
|
||||
import jadx.core.dex.info.FieldInfo;
|
||||
import jadx.core.dex.instructions.IndexInsnNode;
|
||||
|
||||
@@ -8,7 +8,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import jadx.core.dex.attributes.AFlag;
|
||||
import jadx.core.dex.attributes.AType;
|
||||
import jadx.core.dex.attributes.FieldInitAttr;
|
||||
import jadx.core.dex.attributes.fldinit.FieldInitAttr;
|
||||
import jadx.core.dex.info.FieldInfo;
|
||||
import jadx.core.dex.instructions.ConstClassNode;
|
||||
import jadx.core.dex.instructions.ConstStringNode;
|
||||
@@ -101,7 +101,7 @@ public class InsnUtils {
|
||||
return null;
|
||||
}
|
||||
FieldInitAttr attr = fieldNode.get(AType.FIELD_INIT);
|
||||
if (attr != null && attr.getValueType() == FieldInitAttr.InitType.CONST) {
|
||||
if (attr != null && attr.isConst()) {
|
||||
return EncodedValueUtils.convertToConstValue(root, attr.getEncodedValue());
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -17,7 +17,7 @@ import jadx.core.codegen.CodeWriter;
|
||||
import jadx.core.deobf.NameMapper;
|
||||
import jadx.core.dex.attributes.AFlag;
|
||||
import jadx.core.dex.attributes.AType;
|
||||
import jadx.core.dex.attributes.FieldInitAttr;
|
||||
import jadx.core.dex.attributes.fldinit.FieldInitAttr;
|
||||
import jadx.core.dex.info.AccessInfo;
|
||||
import jadx.core.dex.info.ClassInfo;
|
||||
import jadx.core.dex.info.ConstStorage;
|
||||
|
||||
@@ -7,7 +7,7 @@ import java.util.Map;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jadx.core.dex.attributes.AType;
|
||||
import jadx.core.dex.attributes.FieldInitAttr;
|
||||
import jadx.core.dex.attributes.fldinit.FieldInitAttr;
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
import jadx.core.dex.nodes.FieldNode;
|
||||
import jadx.tests.api.IntegrationTest;
|
||||
|
||||
+22
-1
@@ -1,7 +1,9 @@
|
||||
package jadx.api.plugins.input.data.annotations;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class EncodedValue {
|
||||
public static final EncodedValue NULL = new EncodedValue(EncodedType.ENCODED_NULL, new Object());
|
||||
public static final EncodedValue NULL = new EncodedValue(EncodedType.ENCODED_NULL, null);
|
||||
|
||||
private final EncodedType type;
|
||||
private final Object value;
|
||||
@@ -19,9 +21,28 @@ public class EncodedValue {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
EncodedValue that = (EncodedValue) o;
|
||||
return type == that.getType() && Objects.equals(value, that.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(getType(), getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
switch (type) {
|
||||
case ENCODED_NULL:
|
||||
return "null";
|
||||
case ENCODED_STRING:
|
||||
return (String) value;
|
||||
case ENCODED_ARRAY:
|
||||
|
||||
Reference in New Issue
Block a user