Commit dae882d5 authored by Skylot's avatar Skylot

fix: improve generated code on errors

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