Commit 2b300341 authored by Skylot's avatar Skylot

core: improve error reporting for inconsistent code

parent 01fabca3
......@@ -6,7 +6,6 @@ import jadx.core.dex.attributes.AttributeFlag;
import jadx.core.dex.attributes.AttributeType;
import jadx.core.dex.attributes.EnumClassAttr;
import jadx.core.dex.attributes.EnumClassAttr.EnumField;
import jadx.core.dex.attributes.IAttribute;
import jadx.core.dex.attributes.SourceFileAttr;
import jadx.core.dex.info.AccessInfo;
import jadx.core.dex.info.ClassInfo;
......@@ -236,17 +235,20 @@ public class ClassGen {
code.add(';');
} else {
MethodGen mthGen = new MethodGen(this, mth);
if (mth.getAttributes().contains(AttributeFlag.INCONSISTENT_CODE)) {
code.startLine("/* JADX WARNING: inconsistent code */");
boolean badCode = mth.getAttributes().contains(AttributeFlag.INCONSISTENT_CODE);
if (badCode) {
code.startLine("/* JADX WARNING: inconsistent code. */");
code.startLine("/* Code decompiled incorrectly, please refer to instructions dump. */");
LOG.error(ErrorsCounter.formatErrorMsg(mth, " Inconsistent code"));
mthGen.makeMethodDump(code);
}
if (mthGen.addDefinition(code)) {
code.add(' ');
}
code.add('{');
code.incIndent();
insertSourceFileInfo(code, mth);
code.add(mthGen.makeInstructions(code.getIndent()));
mthGen.addInstructions(code);
code.decIndent();
code.startLine('}');
}
} catch (Throwable e) {
......@@ -263,6 +265,33 @@ public class ClassGen {
private CodeWriter makeFields(CodeWriter clsCode, ClassNode cls, List<FieldNode> fields) throws CodegenException {
CodeWriter code = new CodeWriter(clsCode.getIndent() + 1);
addEnumFields(cls, code);
for (FieldNode f : fields) {
if (f.getAttributes().contains(AttributeFlag.DONT_GENERATE)) {
continue;
}
annotationGen.addForField(code, f);
code.startLine(f.getAccessFlags().makeString());
code.add(TypeGen.translate(this, f.getType()));
code.add(' ');
code.add(f.getName());
FieldValueAttr fv = (FieldValueAttr) f.getAttributes().get(AttributeType.FIELD_VALUE);
if (fv != null) {
code.add(" = ");
if (fv.getValue() == null) {
code.add(TypeGen.literalToString(0, f.getType()));
} else {
code.add(annotationGen.encValueToString(fv.getValue()));
}
}
code.add(';');
code.attachAnnotation(f);
}
return code;
}
private void addEnumFields(ClassNode cls, CodeWriter code) throws CodegenException {
EnumClassAttr enumFields = (EnumClassAttr) cls.getAttributes().get(AttributeType.ENUM_CLASS);
if (enumFields != null) {
InsnGen igen = null;
......@@ -278,7 +307,7 @@ public class ClassGen {
MethodGen mthGen = new MethodGen(this, enumFields.getStaticMethod());
igen = new InsnGen(mthGen, enumFields.getStaticMethod(), false);
}
code.add(igen.arg(arg));
igen.addArg(code, arg);
if (aIt.hasNext()) {
code.add(", ");
}
......@@ -298,29 +327,6 @@ public class ClassGen {
code.add(';');
code.newLine();
}
for (FieldNode f : fields) {
if (f.getAttributes().contains(AttributeFlag.DONT_GENERATE)) {
continue;
}
annotationGen.addForField(code, f);
code.startLine(f.getAccessFlags().makeString());
code.add(TypeGen.translate(this, f.getType()));
code.add(' ');
code.add(f.getName());
FieldValueAttr fv = (FieldValueAttr) f.getAttributes().get(AttributeType.FIELD_VALUE);
if (fv != null) {
code.add(" = ");
if (fv.getValue() == null) {
code.add(TypeGen.literalToString(0, f.getType()));
} else {
code.add(annotationGen.encValueToString(fv.getValue()));
}
}
code.add(';');
code.attachAnnotation(f);
}
return code;
}
public String useClass(ArgType clsType) {
......@@ -357,9 +363,9 @@ public class ClassGen {
}
private String useClassInternal(ClassInfo useCls, ClassInfo classInfo) {
String clsStr = classInfo.getFullName();
String fullName = classInfo.getFullName();
if (fallback) {
return clsStr;
return fullName;
}
String shortName = classInfo.getShortName();
if (classInfo.getPackage().equals("java.lang") && classInfo.getParentClass() == null) {
......@@ -374,15 +380,15 @@ public class ClassGen {
return shortName;
}
if (classInfo.getPackage().equals(useCls.getPackage())) {
clsStr = classInfo.getNameWithoutPackage();
fullName = classInfo.getNameWithoutPackage();
}
if (searchCollision(cls.dex(), useCls, shortName)) {
return clsStr;
return fullName;
}
for (ClassInfo importCls : imports) {
if (!importCls.equals(classInfo)
&& importCls.getShortName().equals(shortName)) {
return clsStr;
return fullName;
}
}
addImport(classInfo);
......@@ -425,10 +431,9 @@ public class ClassGen {
}
private void insertSourceFileInfo(CodeWriter code, AttrNode node) {
IAttribute sourceFileAttr = node.getAttributes().get(AttributeType.SOURCE_FILE);
SourceFileAttr sourceFileAttr = (SourceFileAttr) node.getAttributes().get(AttributeType.SOURCE_FILE);
if (sourceFileAttr != null) {
code.startLine("// compiled from: ");
code.add(((SourceFileAttr) sourceFileAttr).getFileName());
code.startLine("// compiled from: ").add(sourceFileAttr.getFileName());
}
}
......
......@@ -12,6 +12,7 @@ import jadx.core.dex.instructions.args.NamedArg;
import jadx.core.dex.instructions.args.RegisterArg;
import jadx.core.dex.nodes.InsnNode;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.dex.regions.Region;
import jadx.core.dex.trycatch.CatchAttr;
import jadx.core.dex.visitors.DepthTraverser;
import jadx.core.dex.visitors.FallbackModeVisitor;
......@@ -227,16 +228,14 @@ public class MethodGen {
return r;
}
public CodeWriter makeInstructions(int mthIndent) throws CodegenException {
CodeWriter code = new CodeWriter(mthIndent + 1);
public void addInstructions(CodeWriter code) throws CodegenException {
if (mth.getAttributes().contains(AttributeType.JADX_ERROR)) {
code.startLine("throw new UnsupportedOperationException(\"Method not decompiled: ");
code.add(mth.toString());
code.add("\");");
JadxErrorAttr err = (JadxErrorAttr) mth.getAttributes().get(AttributeType.JADX_ERROR);
code.startLine("// jadx: method processing error");
code.startLine("/* JADX: method processing error */");
Throwable cause = err.getCause();
if (cause != null) {
code.newLine();
......@@ -245,32 +244,35 @@ public class MethodGen {
code.add("*/");
}
makeMethodDump(code);
} else if (mth.getAttributes().contains(AttributeFlag.INCONSISTENT_CODE)) {
code.startLine("/*");
addFallbackMethodCode(code);
code.startLine("*/");
code.newLine();
} else {
if (mth.getRegion() != null) {
CodeWriter insns = new CodeWriter(mthIndent + 1);
(new RegionGen(this, mth)).makeRegion(insns, mth.getRegion());
code.add(insns);
Region startRegion = mth.getRegion();
if (startRegion != null) {
(new RegionGen(this, mth)).makeRegion(code, startRegion);
} else {
makeFallbackMethod(code, mth);
addFallbackMethodCode(code);
}
}
return code;
}
public void makeMethodDump(CodeWriter code) {
private void makeMethodDump(CodeWriter code) {
code.startLine("/*");
getFallbackMethodGen(mth).addDefinition(code);
code.add(" {");
code.incIndent();
makeFallbackMethod(code, mth);
addFallbackMethodCode(code);
code.decIndent();
code.startLine('}');
code.startLine("*/");
}
private static void makeFallbackMethod(CodeWriter code, MethodNode mth) {
public void addFallbackMethodCode(CodeWriter code) {
if (mth.getInstructions() == null) {
// loadFile original instructions
try {
......@@ -285,10 +287,10 @@ public class MethodGen {
if (mth.getThisArg() != null) {
code.startLine(getFallbackMethodGen(mth).makeArgName(mth.getThisArg())).add(" = this;");
}
makeFallbackInsns(code, mth, mth.getInstructions(), true);
addFallbackInsns(code, mth, mth.getInstructions(), true);
}
public static void makeFallbackInsns(CodeWriter code, MethodNode mth, List<InsnNode> insns, boolean addLabels) {
public static void addFallbackInsns(CodeWriter code, MethodNode mth, List<InsnNode> insns, boolean addLabels) {
InsnGen insnGen = new InsnGen(getFallbackMethodGen(mth), mth, true);
for (InsnNode insn : insns) {
AttributesList attrs = insn.getAttributes();
......
......@@ -165,7 +165,7 @@ public class DotGraphVisitor extends AbstractVisitor {
return str.toString();
} else {
CodeWriter code = new CodeWriter(0);
MethodGen.makeFallbackInsns(code, mth, block.getInstructions(), false);
MethodGen.addFallbackInsns(code, mth, block.getInstructions(), false);
String str = escape(code.newLine().toString());
if (str.startsWith(NL)) {
str = str.substring(NL.length());
......
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