Commit dae882d5 authored by Skylot's avatar Skylot

fix: improve generated code on errors

parent c0a0bba5
......@@ -370,7 +370,7 @@ public class ClassGen {
if (fv != null) {
code.add(" = ");
if (fv.getValue() == null) {
code.add(TypeGen.literalToString(0, f.getType(), cls));
code.add(TypeGen.literalToString(0, f.getType(), cls, fallback));
} else {
if (fv.getValueType() == InitType.CONST) {
annotationGen.encodeValue(code, fv.getValue());
......
......@@ -138,7 +138,7 @@ public class InsnGen {
}
private String lit(LiteralArg arg) {
return TypeGen.literalToString(arg.getLiteral(), arg.getType(), mth);
return TypeGen.literalToString(arg.getLiteral(), arg.getType(), mth, fallback);
}
private void instanceField(CodeWriter code, FieldInfo field, InsnArg arg) throws CodegenException {
......
......@@ -148,7 +148,13 @@ public class MethodGen {
if (var.isFinal()) {
code.add("final ");
}
ArgType argType = var.getType();
ArgType argType;
if (var.getType() == ArgType.UNKNOWN) {
// occur on decompilation errors
argType = mthArg.getInitType();
} else {
argType = var.getType();
}
if (!it.hasNext() && mth.getAccessFlags().isVarArgs()) {
// change last array argument to varargs
if (argType.isArray()) {
......
......@@ -266,7 +266,7 @@ public class RegionGen extends InsnGen {
}
}
} else if (k instanceof Integer) {
code.add(TypeGen.literalToString((Integer) k, arg.getType(), mth));
code.add(TypeGen.literalToString((Integer) k, arg.getType(), mth, fallback));
} else {
throw new JadxRuntimeException("Unexpected key in switch: " + (k != null ? k.getClass() : null));
}
......
......@@ -33,14 +33,14 @@ public class TypeGen {
*
* @throws JadxRuntimeException for incorrect type or literal value
*/
public static String literalToString(long lit, ArgType type, IDexNode dexNode) {
return literalToString(lit, type, dexNode.root().getStringUtils());
public static String literalToString(long lit, ArgType type, IDexNode dexNode, boolean fallback) {
return literalToString(lit, type, dexNode.root().getStringUtils(), fallback);
}
public static String literalToString(long lit, ArgType type, StringUtils stringUtils) {
public static String literalToString(long lit, ArgType type, StringUtils stringUtils, boolean fallback) {
if (type == null || !type.isTypeKnown()) {
String n = Long.toString(lit);
if (Math.abs(lit) > 100) {
if (fallback && Math.abs(lit) > 100) {
StringBuilder sb = new StringBuilder();
sb.append(n).append("(0x").append(Long.toHexString(lit));
if (type == null || type.contains(PrimitiveType.FLOAT)) {
......
......@@ -70,7 +70,7 @@ public final class LiteralArg extends InsnArg {
@Override
public String toString() {
try {
String value = TypeGen.literalToString(literal, getType(), DEF_STRING_UTILS);
String value = TypeGen.literalToString(literal, getType(), DEF_STRING_UTILS, true);
if (getType().equals(ArgType.BOOLEAN) && (value.equals("true") || value.equals("false"))) {
return value;
}
......
......@@ -5,11 +5,15 @@ import java.util.List;
import org.jetbrains.annotations.Nullable;
import com.android.dx.rop.code.AccessFlags;
import jadx.core.codegen.TypeGen;
import jadx.core.deobf.NameMapper;
import jadx.core.dex.attributes.AFlag;
import jadx.core.dex.attributes.AType;
import jadx.core.dex.attributes.nodes.EnumClassAttr;
import jadx.core.dex.attributes.nodes.EnumClassAttr.EnumField;
import jadx.core.dex.info.AccessInfo;
import jadx.core.dex.info.ClassInfo;
import jadx.core.dex.info.FieldInfo;
import jadx.core.dex.info.MethodInfo;
......@@ -41,6 +45,11 @@ public class EnumVisitor extends AbstractVisitor {
@Override
public boolean visit(ClassNode cls) throws JadxException {
if (!cls.isEnum()) {
AccessInfo accessFlags = cls.getAccessFlags();
if (accessFlags.isEnum()) {
cls.setAccessFlags(accessFlags.remove(AccessFlags.ACC_ENUM));
cls.addAttr(AType.COMMENTS, "'enum' access flag removed");
}
return true;
}
// search class init method
......
......@@ -28,7 +28,7 @@ public class FixAccessModifiers extends AbstractVisitor {
return;
}
int newVisFlag = fixVisibility(mth);
if (newVisFlag != 0) {
if (newVisFlag != -1) {
changeVisibility(mth, newVisFlag);
}
}
......@@ -38,7 +38,7 @@ public class FixAccessModifiers extends AbstractVisitor {
AccessInfo newAccFlags = accessFlags.changeVisibility(newVisFlag);
if (newAccFlags != accessFlags) {
node.setAccessFlags(newAccFlags);
node.addAttr(AType.COMMENTS, "access modifiers changed from: " + accessFlags.rawString());
node.addAttr(AType.COMMENTS, "access modifiers changed from: " + accessFlags.getVisibility().rawString());
}
}
......@@ -52,9 +52,15 @@ public class FixAccessModifiers extends AbstractVisitor {
// make abstract methods public
return AccessFlags.ACC_PUBLIC;
}
// enum constructor can't be public
if (accessFlags.isConstructor()
&& accessFlags.isPublic()
&& mth.getParentClass().isEnum()) {
return 0;
}
if (accessFlags.isConstructor() || accessFlags.isStatic()) {
// TODO: make public if used outside
return 0;
return -1;
}
// make other direct methods private
return AccessFlags.ACC_PRIVATE;
......
......@@ -103,7 +103,9 @@ public class LoopRegionVisitor extends AbstractVisitor implements IRegionVisitor
}
RegisterArg initArg = phiInsn.getArg(0);
InsnNode initInsn = initArg.getAssignInsn();
if (initInsn == null || initArg.getSVar().getUseCount() != 1) {
if (initInsn == null
|| initInsn.contains(AFlag.DONT_GENERATE)
|| initArg.getSVar().getUseCount() != 1) {
return false;
}
if (!usedOnlyInLoop(mth, loopRegion, arg)) {
......
......@@ -44,6 +44,6 @@ public class TestEnums3 extends IntegrationTest {
assertThat(code, containsOne("ONE(1)"));
// assertThat(code, containsOne("THREE(three)"));
// assertThat(code, containsOne("assertTrue(Numbers.ONE.getNum() == 1);"));
assertThat(code, containsOne("private Numbers(int n) {"));
assertThat(code, containsOne("Numbers(int n) {"));
}
}
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