Commit 890c0a99 authored by Skylot's avatar Skylot

refactor: remove deprecated methods

parent b73cb406
...@@ -151,8 +151,7 @@ public class AnnotationGen { ...@@ -151,8 +151,7 @@ public class AnnotationGen {
code.add(InsnGen.makeStaticFieldAccess(field, classGen)); code.add(InsnGen.makeStaticFieldAccess(field, classGen));
} else if (val instanceof List) { } else if (val instanceof List) {
code.add('{'); code.add('{');
List list = (List) val; Iterator<?> it = ((List) val).iterator();
Iterator it = list.iterator();
while (it.hasNext()) { while (it.hasNext()) {
Object obj = it.next(); Object obj = it.next();
encodeValue(code, obj); encodeValue(code, obj);
......
...@@ -43,6 +43,7 @@ public class ClassGen { ...@@ -43,6 +43,7 @@ public class ClassGen {
private final boolean fallback; private final boolean fallback;
private final Set<ClassInfo> imports = new HashSet<ClassInfo>(); private final Set<ClassInfo> imports = new HashSet<ClassInfo>();
private int clsDeclLine = 0;
public ClassGen(ClassNode cls, ClassGen parentClsGen, boolean fallback) { public ClassGen(ClassNode cls, ClassGen parentClsGen, boolean fallback) {
this.cls = cls; this.cls = cls;
...@@ -95,12 +96,11 @@ public class ClassGen { ...@@ -95,12 +96,11 @@ public class ClassGen {
if (cls.getAttributes().contains(AttributeFlag.INCONSISTENT_CODE)) { if (cls.getAttributes().contains(AttributeFlag.INCONSISTENT_CODE)) {
code.startLine("// jadx: inconsistent code"); code.startLine("// jadx: inconsistent code");
} }
makeClassDeclaration(code); addClassDeclaration(code);
makeClassBody(code); addClassBody(code);
code.newLine();
} }
public void makeClassDeclaration(CodeWriter clsCode) { public void addClassDeclaration(CodeWriter clsCode) {
AccessInfo af = cls.getAccessFlags(); AccessInfo af = cls.getAccessFlags();
if (af.isInterface()) { if (af.isInterface()) {
af = af.remove(AccessFlags.ACC_ABSTRACT); af = af.remove(AccessFlags.ACC_ABSTRACT);
...@@ -123,7 +123,7 @@ public class ClassGen { ...@@ -123,7 +123,7 @@ public class ClassGen {
} }
clsCode.add(cls.getShortName()); clsCode.add(cls.getShortName());
makeGenericMap(clsCode, cls.getGenericMap()); addGenericMap(clsCode, cls.getGenericMap());
clsCode.add(' '); clsCode.add(' ');
ClassInfo sup = cls.getSuperClass(); ClassInfo sup = cls.getSuperClass();
...@@ -150,11 +150,10 @@ public class ClassGen { ...@@ -150,11 +150,10 @@ public class ClassGen {
clsCode.add(' '); clsCode.add(' ');
} }
} }
clsCode.attachDefinition(cls); clsCode.attachDefinition(cls);
} }
public boolean makeGenericMap(CodeWriter code, Map<ArgType, List<ArgType>> gmap) { public boolean addGenericMap(CodeWriter code, Map<ArgType, List<ArgType>> gmap) {
if (gmap == null || gmap.isEmpty()) { if (gmap == null || gmap.isEmpty()) {
return false; return false;
} }
...@@ -183,91 +182,78 @@ public class ClassGen { ...@@ -183,91 +182,78 @@ public class ClassGen {
return true; return true;
} }
public void makeClassBody(CodeWriter clsCode) throws CodegenException { public void addClassBody(CodeWriter clsCode) throws CodegenException {
clsCode.add('{'); clsCode.add('{');
CodeWriter mthsCode = makeMethods(clsCode, cls.getMethods()); clsDeclLine = clsCode.getLine();
CodeWriter fieldsCode = makeFields(clsCode, cls, cls.getFields()); clsCode.incIndent();
clsCode.add(fieldsCode); addFields(clsCode);
if (fieldsCode.notEmpty() && mthsCode.notEmpty()) { addInnerClasses(clsCode, cls);
clsCode.newLine(); addMethods(clsCode);
} clsCode.decIndent();
// insert inner classes code
if (cls.getInnerClasses().size() != 0) {
clsCode.add(makeInnerClasses(cls, clsCode.getIndent()));
if (mthsCode.notEmpty()) {
clsCode.newLine();
}
}
clsCode.add(mthsCode);
clsCode.startLine('}'); clsCode.startLine('}');
} }
private CodeWriter makeInnerClasses(ClassNode cls, int indent) throws CodegenException { private void addInnerClasses(CodeWriter code, ClassNode cls) throws CodegenException {
CodeWriter innerClsCode = new CodeWriter(indent + 1); for (ClassNode innerCls : cls.getInnerClasses()) {
for (ClassNode inCls : cls.getInnerClasses()) { if (!innerCls.isAnonymous()) {
if (!inCls.isAnonymous()) { ClassGen inClGen = new ClassGen(innerCls, getParentGen(), fallback);
ClassGen inClGen = new ClassGen(inCls, parentGen == null ? this : parentGen, fallback); code.newLine();
inClGen.addClassCode(innerClsCode); inClGen.addClassCode(code);
imports.addAll(inClGen.getImports()); imports.addAll(inClGen.getImports());
} }
} }
return innerClsCode;
} }
private CodeWriter makeMethods(CodeWriter clsCode, List<MethodNode> mthList) { private void addMethods(CodeWriter code) {
CodeWriter code = new CodeWriter(clsCode.getIndent() + 1); for (MethodNode mth : cls.getMethods()) {
for (Iterator<MethodNode> it = mthList.iterator(); it.hasNext(); ) { if (!mth.getAttributes().contains(AttributeFlag.DONT_GENERATE)) {
MethodNode mth = it.next(); try {
if (mth.getAttributes().contains(AttributeFlag.DONT_GENERATE)) { if (code.getLine() != clsDeclLine) {
continue; code.newLine();
}
try {
if (mth.getAccessFlags().isAbstract() || mth.getAccessFlags().isNative()) {
MethodGen mthGen = new MethodGen(this, mth);
mthGen.addDefinition(code);
if (cls.getAccessFlags().isAnnotation()) {
Object def = annotationGen.getAnnotationDefaultValue(mth.getName());
if (def != null) {
code.add(" default ");
annotationGen.encodeValue(code, def);
}
}
code.add(';');
} else {
MethodGen mthGen = new MethodGen(this, mth);
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"));
}
if (mthGen.addDefinition(code)) {
code.add(' ');
} }
code.add('{'); addMethod(code, mth);
code.incIndent(); } catch (Exception e) {
insertSourceFileInfo(code, mth); String msg = ErrorsCounter.methodError(mth, "Method generation error", e);
mthGen.addInstructions(code); code.startLine("/* " + msg + CodeWriter.NL + Utils.getStackTrace(e) + " */");
code.decIndent();
code.startLine('}');
} }
} catch (Throwable e) {
String msg = ErrorsCounter.methodError(mth, "Method generation error", e);
code.startLine("/* " + msg + CodeWriter.NL + Utils.getStackTrace(e) + " */");
}
if (it.hasNext()) {
code.newLine();
} }
} }
return code;
} }
private CodeWriter makeFields(CodeWriter clsCode, ClassNode cls, List<FieldNode> fields) throws CodegenException { private void addMethod(CodeWriter code, MethodNode mth) throws CodegenException {
CodeWriter code = new CodeWriter(clsCode.getIndent() + 1); MethodGen mthGen = new MethodGen(this, mth);
if (mth.getAccessFlags().isAbstract() || mth.getAccessFlags().isNative()) {
addEnumFields(cls, code); mthGen.addDefinition(code);
if (cls.getAccessFlags().isAnnotation()) {
Object def = annotationGen.getAnnotationDefaultValue(mth.getName());
if (def != null) {
code.add(" default ");
annotationGen.encodeValue(code, def);
}
}
code.add(';');
} else {
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"));
}
if (mthGen.addDefinition(code)) {
code.add(' ');
}
code.add('{');
code.incIndent();
insertSourceFileInfo(code, mth);
mthGen.addInstructions(code);
code.decIndent();
code.startLine('}');
}
}
for (FieldNode f : fields) { private void addFields(CodeWriter code) throws CodegenException {
addEnumFields(code);
for (FieldNode f : cls.getFields()) {
if (f.getAttributes().contains(AttributeFlag.DONT_GENERATE)) { if (f.getAttributes().contains(AttributeFlag.DONT_GENERATE)) {
continue; continue;
} }
...@@ -288,10 +274,9 @@ public class ClassGen { ...@@ -288,10 +274,9 @@ public class ClassGen {
code.add(';'); code.add(';');
code.attachDefinition(f); code.attachDefinition(f);
} }
return code;
} }
private void addEnumFields(ClassNode cls, CodeWriter code) throws CodegenException { private void addEnumFields(CodeWriter code) throws CodegenException {
EnumClassAttr enumFields = (EnumClassAttr) cls.getAttributes().get(AttributeType.ENUM_CLASS); EnumClassAttr enumFields = (EnumClassAttr) cls.getAttributes().get(AttributeType.ENUM_CLASS);
if (enumFields != null) { if (enumFields != null) {
InsnGen igen = null; InsnGen igen = null;
...@@ -305,7 +290,7 @@ public class ClassGen { ...@@ -305,7 +290,7 @@ public class ClassGen {
if (igen == null) { if (igen == null) {
// don't init mth gen if this is simple enum // don't init mth gen if this is simple enum
MethodGen mthGen = new MethodGen(this, enumFields.getStaticMethod()); MethodGen mthGen = new MethodGen(this, enumFields.getStaticMethod());
igen = new InsnGen(mthGen, enumFields.getStaticMethod(), false); igen = new InsnGen(mthGen, false);
} }
igen.addArg(code, arg); igen.addArg(code, arg);
if (aIt.hasNext()) { if (aIt.hasNext()) {
...@@ -315,7 +300,7 @@ public class ClassGen { ...@@ -315,7 +300,7 @@ public class ClassGen {
code.add(')'); code.add(')');
} }
if (f.getCls() != null) { if (f.getCls() != null) {
new ClassGen(f.getCls(), this, fallback).makeClassBody(code); new ClassGen(f.getCls(), this, fallback).addClassBody(code);
} }
if (it.hasNext()) { if (it.hasNext()) {
code.add(','); code.add(',');
......
...@@ -95,21 +95,15 @@ public class CodeWriter { ...@@ -95,21 +95,15 @@ public class CodeWriter {
return this; return this;
} }
@Deprecated CodeWriter add(CodeWriter code) {
public CodeWriter add(CodeWriter code) {
line--; line--;
for (Map.Entry<CodePosition, Object> entry : code.annotations.entrySet()) { for (Map.Entry<CodePosition, Object> entry : code.annotations.entrySet()) {
CodePosition pos = entry.getKey(); CodePosition pos = entry.getKey();
attachAnnotation(entry.getValue(), new CodePosition(line + pos.getLine(), pos.getOffset())); attachAnnotation(entry.getValue(), new CodePosition(line + pos.getLine(), pos.getOffset()));
} }
line += code.line; line += code.line;
String str = code.toString(); offset = code.offset;
buf.append(str); buf.append(code);
if (str.contains(NL)) {
offset = code.offset;
} else {
offset += code.offset;
}
return this; return this;
} }
...@@ -143,6 +137,10 @@ public class CodeWriter { ...@@ -143,6 +137,10 @@ public class CodeWriter {
} }
} }
public int getLine() {
return line;
}
public int getIndent() { public int getIndent() {
return indent; return indent;
} }
......
...@@ -12,41 +12,52 @@ import jadx.core.dex.regions.Compare; ...@@ -12,41 +12,52 @@ import jadx.core.dex.regions.Compare;
import jadx.core.dex.regions.IfCondition; import jadx.core.dex.regions.IfCondition;
import jadx.core.utils.ErrorsCounter; import jadx.core.utils.ErrorsCounter;
import jadx.core.utils.exceptions.CodegenException; import jadx.core.utils.exceptions.CodegenException;
import jadx.core.utils.exceptions.JadxRuntimeException;
import java.util.Iterator;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
public class ConditionGen { public class ConditionGen extends InsnGen {
private static final Logger LOG = LoggerFactory.getLogger(ConditionGen.class); private static final Logger LOG = LoggerFactory.getLogger(ConditionGen.class);
static String make(InsnGen insnGen, IfCondition condition) throws CodegenException { public ConditionGen(InsnGen insnGen) {
super(insnGen.mgen, insnGen.fallback);
}
void add(CodeWriter code, IfCondition condition) throws CodegenException {
switch (condition.getMode()) { switch (condition.getMode()) {
case COMPARE: case COMPARE:
return makeCompare(insnGen, condition.getCompare()); addCompare(code, condition.getCompare());
break;
case NOT: case NOT:
return "!(" + make(insnGen, condition.getArgs().get(0)) + ")"; addNot(code, condition);
break;
case AND: case AND:
case OR: case OR:
String mode = condition.getMode() == IfCondition.Mode.AND ? " && " : " || "; addAndOr(code, condition);
StringBuilder sb = new StringBuilder(); break;
for (IfCondition arg : condition.getArgs()) {
if (sb.length() != 0) {
sb.append(mode);
}
String s = make(insnGen, arg);
if (arg.isCompare()) {
sb.append(s);
} else {
sb.append('(').append(s).append(')');
}
}
return sb.toString();
default: default:
return "??" + condition; throw new JadxRuntimeException("Unknown condition mode: " + condition);
}
}
void wrap(CodeWriter code, IfCondition cond) throws CodegenException {
boolean wrap = isWrapNeeded(cond);
if (wrap) {
code.add('(');
}
add(code, cond);
if (wrap) {
code.add(')');
} }
} }
private static String makeCompare(InsnGen insnGen, Compare compare) throws CodegenException { private void addCompare(CodeWriter code, Compare compare) throws CodegenException {
IfOp op = compare.getOp(); IfOp op = compare.getOp();
InsnArg firstArg = compare.getA(); InsnArg firstArg = compare.getA();
InsnArg secondArg = compare.getB(); InsnArg secondArg = compare.getB();
...@@ -59,20 +70,47 @@ public class ConditionGen { ...@@ -59,20 +70,47 @@ public class ConditionGen {
} }
if (op == IfOp.EQ) { if (op == IfOp.EQ) {
// == true // == true
return insnGen.arg(firstArg, false).toString(); addArg(code, firstArg, false);
return;
} else if (op == IfOp.NE) { } else if (op == IfOp.NE) {
// != true // != true
if (isWrapNeeded(firstArg)) { code.add('!');
return "!(" + insnGen.arg(firstArg) + ")"; boolean wrap = isWrapNeeded(firstArg);
} else { if (wrap) {
return "!" + insnGen.arg(firstArg); code.add('(');
} }
addArg(code, firstArg, false);
if (wrap) {
code.add(')');
}
return;
}
LOG.warn(ErrorsCounter.formatErrorMsg(mth, "Unsupported boolean condition " + op.getSymbol()));
}
addArg(code, firstArg, isWrapNeeded(firstArg));
code.add(' ').add(op.getSymbol()).add(' ');
addArg(code, secondArg, isWrapNeeded(secondArg));
}
private void addNot(CodeWriter code, IfCondition condition) throws CodegenException {
code.add('!');
wrap(code, condition.getArgs().get(0));
}
private void addAndOr(CodeWriter code, IfCondition condition) throws CodegenException {
String mode = condition.getMode() == IfCondition.Mode.AND ? " && " : " || ";
Iterator<IfCondition> it = condition.getArgs().iterator();
while (it.hasNext()) {
wrap(code, it.next());
if (it.hasNext()) {
code.add(mode);
} }
LOG.warn(ErrorsCounter.formatErrorMsg(insnGen.mth, "Unsupported boolean condition " + op.getSymbol()));
} }
return insnGen.arg(firstArg, isWrapNeeded(firstArg)) }
+ " " + op.getSymbol() + " "
+ insnGen.arg(secondArg, isWrapNeeded(secondArg)); private boolean isWrapNeeded(IfCondition condition) {
return !condition.isCompare();
} }
private static boolean isWrapNeeded(InsnArg arg) { private static boolean isWrapNeeded(InsnArg arg) {
......
...@@ -58,6 +58,10 @@ public class MethodGen { ...@@ -58,6 +58,10 @@ public class MethodGen {
return classGen; return classGen;
} }
public MethodNode getMethodNode() {
return mth;
}
public boolean addDefinition(CodeWriter code) { public boolean addDefinition(CodeWriter code) {
if (mth.getMethodInfo().isClassInit()) { if (mth.getMethodInfo().isClassInit()) {
code.startLine("static"); code.startLine("static");
...@@ -84,7 +88,7 @@ public class MethodGen { ...@@ -84,7 +88,7 @@ public class MethodGen {
} }
code.startLine(ai.makeString()); code.startLine(ai.makeString());
if (classGen.makeGenericMap(code, mth.getGenericMap())) { if (classGen.addGenericMap(code, mth.getGenericMap())) {
code.add(' '); code.add(' ');
} }
if (mth.getAccessFlags().isConstructor()) { if (mth.getAccessFlags().isConstructor()) {
...@@ -245,7 +249,7 @@ public class MethodGen { ...@@ -245,7 +249,7 @@ public class MethodGen {
} else { } else {
Region startRegion = mth.getRegion(); Region startRegion = mth.getRegion();
if (startRegion != null) { if (startRegion != null) {
(new RegionGen(this, mth)).makeRegion(code, startRegion); (new RegionGen(this)).makeRegion(code, startRegion);
} else { } else {
addFallbackMethodCode(code); addFallbackMethodCode(code);
} }
...@@ -289,7 +293,7 @@ public class MethodGen { ...@@ -289,7 +293,7 @@ public class MethodGen {
} }
public static void addFallbackInsns(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); InsnGen insnGen = new InsnGen(getFallbackMethodGen(mth), true);
for (InsnNode insn : insns) { for (InsnNode insn : insns) {
AttributesList attrs = insn.getAttributes(); AttributesList attrs = insn.getAttributes();
if (addLabels) { if (addLabels) {
......
...@@ -15,7 +15,6 @@ import jadx.core.dex.nodes.IBlock; ...@@ -15,7 +15,6 @@ import jadx.core.dex.nodes.IBlock;
import jadx.core.dex.nodes.IContainer; import jadx.core.dex.nodes.IContainer;
import jadx.core.dex.nodes.IRegion; import jadx.core.dex.nodes.IRegion;
import jadx.core.dex.nodes.InsnNode; import jadx.core.dex.nodes.InsnNode;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.dex.regions.IfCondition; import jadx.core.dex.regions.IfCondition;
import jadx.core.dex.regions.IfRegion; import jadx.core.dex.regions.IfRegion;
import jadx.core.dex.regions.LoopRegion; import jadx.core.dex.regions.LoopRegion;
...@@ -36,8 +35,8 @@ import org.slf4j.LoggerFactory; ...@@ -36,8 +35,8 @@ import org.slf4j.LoggerFactory;
public class RegionGen extends InsnGen { public class RegionGen extends InsnGen {
private static final Logger LOG = LoggerFactory.getLogger(RegionGen.class); private static final Logger LOG = LoggerFactory.getLogger(RegionGen.class);
public RegionGen(MethodGen mgen, MethodNode mth) { public RegionGen(MethodGen mgen) {
super(mgen, mth, false); super(mgen, false);
} }
public void makeRegion(CodeWriter code, IContainer cont) throws CodegenException { public void makeRegion(CodeWriter code, IContainer cont) throws CodegenException {
...@@ -66,7 +65,9 @@ public class RegionGen extends InsnGen { ...@@ -66,7 +65,9 @@ public class RegionGen extends InsnGen {
(DeclareVariablesAttr) cont.getAttributes().get(AttributeType.DECLARE_VARIABLES); (DeclareVariablesAttr) cont.getAttributes().get(AttributeType.DECLARE_VARIABLES);
if (declVars != null) { if (declVars != null) {
for (RegisterArg v : declVars.getVars()) { for (RegisterArg v : declVars.getVars()) {
code.startLine(declareVar(v)).add(';'); code.startLine();
declareVar(code, v);
code.add(';');
} }
} }
} }
...@@ -111,7 +112,9 @@ public class RegionGen extends InsnGen { ...@@ -111,7 +112,9 @@ public class RegionGen extends InsnGen {
if (newLine) { if (newLine) {
code.startLine(); code.startLine();
} }
code.add("if (").add(ConditionGen.make(this, region.getCondition())).add(") {"); code.add("if (");
new ConditionGen(this).add(code, region.getCondition());
code.add(") {");
makeRegionIndent(code, region.getThenRegion()); makeRegionIndent(code, region.getThenRegion());
code.startLine('}'); code.startLine('}');
...@@ -169,13 +172,17 @@ public class RegionGen extends InsnGen { ...@@ -169,13 +172,17 @@ public class RegionGen extends InsnGen {
return code; return code;
} }
String condStr = ConditionGen.make(this, condition); ConditionGen conditionGen = new ConditionGen(this);
if (region.isConditionAtEnd()) { if (region.isConditionAtEnd()) {
code.startLine("do {"); code.startLine("do {");
makeRegionIndent(code, region.getBody()); makeRegionIndent(code, region.getBody());
code.startLine("} while (").add(condStr).add(");"); code.startLine("} while (");
conditionGen.add(code, condition);
code.add(");");
} else { } else {
code.startLine("while (").add(condStr).add(") {"); code.startLine("while (");
conditionGen.add(code, condition);
code.add(") {");
makeRegionIndent(code, region.getBody()); makeRegionIndent(code, region.getBody());
code.startLine('}'); code.startLine('}');
} }
......
package jadx.core.dex.visitors; package jadx.core.dex.visitors;
import jadx.core.dex.attributes.AttributeFlag; import jadx.core.dex.attributes.AttributeFlag;
import jadx.core.dex.attributes.AttributeType;
import jadx.core.dex.attributes.AttributesList; import jadx.core.dex.attributes.AttributesList;
import jadx.core.dex.attributes.FieldReplaceAttr; import jadx.core.dex.attributes.FieldReplaceAttr;
import jadx.core.dex.info.AccessInfo; import jadx.core.dex.info.AccessInfo;
...@@ -39,6 +40,8 @@ public class ClassModifier extends AbstractVisitor { ...@@ -39,6 +40,8 @@ public class ClassModifier extends AbstractVisitor {
removeSyntheticFields(cls); removeSyntheticFields(cls);
removeSyntheticMethods(cls); removeSyntheticMethods(cls);
removeEmptyMethods(cls); removeEmptyMethods(cls);
checkFieldsInit(cls);
return false; return false;
} }
...@@ -174,4 +177,36 @@ public class ClassModifier extends AbstractVisitor { ...@@ -174,4 +177,36 @@ public class ClassModifier extends AbstractVisitor {
} }
return true; return true;
} }
private static void checkFieldsInit(ClassNode cls) {
MethodNode clinit = cls.searchMethodByName("<clinit>()V");
if (clinit == null
|| !clinit.getAccessFlags().isStatic()
|| clinit.isNoCode()) {
return;
}
for (BlockNode block : clinit.getBasicBlocks()) {
for (InsnNode insn : block.getInstructions()) {
if (insn.getType() == InsnType.SPUT) {
processStaticFieldAssign(cls, (IndexInsnNode) insn);
}
}
}
}
/**
* Remove field initialization if it assign in "<clinit>" method
*/
private static void processStaticFieldAssign(ClassNode cls, IndexInsnNode insn) {
FieldInfo field = (FieldInfo) insn.getIndex();
String thisClass = cls.getFullName();
if (field.getDeclClass().getFullName().equals(thisClass)) {
FieldNode fn = cls.searchField(field);
if (fn != null && fn.getAccessFlags().isFinal()) {
fn.getAttributes().remove(AttributeType.FIELD_VALUE);
}
}
}
} }
...@@ -6,7 +6,6 @@ import jadx.core.dex.nodes.ClassNode; ...@@ -6,7 +6,6 @@ import jadx.core.dex.nodes.ClassNode;
import org.junit.Test; import org.junit.Test;
import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.either;
import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
...@@ -18,10 +17,7 @@ public class TestRedundantBrackets extends InternalJadxTest { ...@@ -18,10 +17,7 @@ public class TestRedundantBrackets extends InternalJadxTest {
} }
public int method2(Object obj) { public int method2(Object obj) {
if (obj instanceof String) { return obj instanceof String ? ((String) obj).length() : 0;
return ((String) obj).length();
}
return 0;
} }
public int method3(int a, int b) { public int method3(int a, int b) {
...@@ -50,11 +46,12 @@ public class TestRedundantBrackets extends InternalJadxTest { ...@@ -50,11 +46,12 @@ public class TestRedundantBrackets extends InternalJadxTest {
public void test() { public void test() {
ClassNode cls = getClassNode(TestCls.class); ClassNode cls = getClassNode(TestCls.class);
String code = cls.getCode().toString(); String code = cls.getCode().toString();
System.out.println(code);
assertThat(code, not(containsString("(-1)"))); assertThat(code, not(containsString("(-1)")));
assertThat(code, not(containsString("return;"))); assertThat(code, not(containsString("return;")));
assertThat(code, either(containsString("if (obj instanceof String) {"))
.or(containsString("return (obj instanceof String) ? "))); assertThat(code, containsString("return obj instanceof String ? ((String) obj).length() : 0;"));
assertThat(code, containsString("if (a + b < 10)")); assertThat(code, containsString("if (a + b < 10)"));
assertThat(code, containsString("if ((a & b) != 0)")); assertThat(code, containsString("if ((a & b) != 0)"));
assertThat(code, containsString("if (num == 4 || num == 6 || num == 8 || num == 10)")); assertThat(code, containsString("if (num == 4 || num == 6 || num == 8 || num == 10)"));
......
...@@ -57,7 +57,7 @@ public class TestReturnWrapping extends InternalJadxTest { ...@@ -57,7 +57,7 @@ public class TestReturnWrapping extends InternalJadxTest {
assertThat(code, containsString("return 255;")); assertThat(code, containsString("return 255;"));
assertThat(code, containsString("return arg0 + 1;")); assertThat(code, containsString("return arg0 + 1;"));
//assertThat(code, containsString("return Integer.toHexString(i);")); //assertThat(code, containsString("return Integer.toHexString(i);"));
assertThat(code, containsString("return (i > 128) ? arg0.toString() + ret.toString() : Integer.valueOf(i);")); assertThat(code, containsString("return i > 128 ? arg0.toString() + ret.toString() : Integer.valueOf(i);"));
assertThat(code, containsString("return arg0 + 2;")); assertThat(code, containsString("return arg0 + 2;"));
assertThat(code, containsString("arg0 -= 951;")); assertThat(code, containsString("arg0 -= 951;"));
} }
......
package jadx.tests.internal;
import jadx.api.InternalJadxTest;
import jadx.core.dex.nodes.ClassNode;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertThat;
public class TestStaticFieldsInit extends InternalJadxTest {
public static class TestCls {
public static final String s1 = "1";
public static final String s2 = "12".substring(1);
public static final String s3 = null;
public static final String s4;
public static final String s5 = "5";
public static String s6 = "6";
static {
if (s5.equals("?")) {
s4 = "?";
} else {
s4 = "4";
}
}
}
@Test
public void test() {
ClassNode cls = getClassNode(TestCls.class);
String code = cls.getCode().toString();
System.out.println(code);
assertThat(code, not(containsString("public static final String s2 = null;")));
// TODO:
// assertThat(code, containsString("public static final String s3 = null;"));
}
}
...@@ -43,6 +43,6 @@ public class TestGenerics2 extends InternalJadxTest { ...@@ -43,6 +43,6 @@ public class TestGenerics2 extends InternalJadxTest {
assertThat(code, containsString("public ItemReference(V item, Object id, ReferenceQueue<? super V> queue) {")); assertThat(code, containsString("public ItemReference(V item, Object id, ReferenceQueue<? super V> queue) {"));
assertThat(code, containsString("public V get(Object id) {")); assertThat(code, containsString("public V get(Object id) {"));
assertThat(code, containsString("WeakReference<V> ref = ")); assertThat(code, containsString("WeakReference<V> ref = "));
assertThat(code, containsString("return (ref != null) ? ref.get() : null;")); assertThat(code, containsString("return ref != null ? ref.get() : null;"));
} }
} }
...@@ -21,6 +21,8 @@ import org.slf4j.LoggerFactory; ...@@ -21,6 +21,8 @@ import org.slf4j.LoggerFactory;
public class JadxTextArea extends RSyntaxTextArea { public class JadxTextArea extends RSyntaxTextArea {
private static final Logger LOG = LoggerFactory.getLogger(JadxTextArea.class); private static final Logger LOG = LoggerFactory.getLogger(JadxTextArea.class);
private static final long serialVersionUID = 6312736869579635796L;
private static final Color BACKGROUND = new Color(0xf7f7f7); private static final Color BACKGROUND = new Color(0xf7f7f7);
private static final Color JUMP_FOREGROUND = new Color(0x785523); private static final Color JUMP_FOREGROUND = new Color(0x785523);
private static final Color JUMP_BACKGROUND = new Color(0xE6E6FF); private static final Color JUMP_BACKGROUND = new Color(0xE6E6FF);
......
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