提交 3c84975a 编写于 作者: S Skylot

fix code style issues

上级 bb4ef4f0
......@@ -68,25 +68,25 @@ public final class JadxCLIArgs implements IJadxArgs {
System.exit(0);
}
try {
if (threadsCount <= 0)
if (threadsCount <= 0) {
throw new JadxException("Threads count must be positive");
}
if (files != null) {
for (String fileName : files) {
File file = new File(fileName);
if (file.exists())
if (file.exists()) {
input.add(file);
else
} else {
throw new JadxException("File not found: " + file);
}
}
}
if (input.size() > 1)
if (input.size() > 1) {
throw new JadxException("Only one input file is supported");
if (outDirName != null)
}
if (outDirName != null) {
outputDir = new File(outDirName);
}
if (isVerbose()) {
ch.qos.logback.classic.Logger rootLogger =
(ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
......@@ -114,8 +114,9 @@ public final class JadxCLIArgs implements IJadxArgs {
int maxNamesLen = 0;
for (ParameterDescription p : params) {
int len = p.getNames().length();
if (len > maxNamesLen)
if (len > maxNamesLen) {
maxNamesLen = len;
}
}
Field[] fields = this.getClass().getDeclaredFields();
......@@ -137,8 +138,9 @@ public final class JadxCLIArgs implements IJadxArgs {
}
private static void addSpaces(StringBuilder str, int count) {
for (int i = 0; i < count; i++)
for (int i = 0; i < count; i++) {
str.append(' ');
}
}
public List<File> getInput() {
......
......@@ -16,7 +16,6 @@ import jadx.core.utils.files.InputFile;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
......@@ -80,7 +79,7 @@ public final class Decompiler {
}
public void loadFile(File file) throws IOException, DecodeException {
loadFiles(Arrays.asList(file));
loadFiles(Collections.singletonList(file));
}
public void loadFiles(List<File> files) throws IOException, DecodeException {
......@@ -110,15 +109,20 @@ public final class Decompiler {
int threadsCount = args.getThreadsCount();
LOG.debug("processing threads count: {}", threadsCount);
ArrayList<IDexTreeVisitor> passList = new ArrayList<IDexTreeVisitor>(passes);
final List<IDexTreeVisitor> passList = new ArrayList<IDexTreeVisitor>(passes);
SaveCode savePass = new SaveCode(outDir, args);
passList.add(savePass);
LOG.info("processing ...");
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(threadsCount);
for (ClassNode cls : root.getClasses(false)) {
for (final ClassNode cls : root.getClasses(false)) {
if (cls.getCode() == null) {
ProcessClass job = new ProcessClass(cls, passList);
Runnable job = new Runnable() {
@Override
public void run() {
ProcessClass.process(cls, passList);
}
};
executor.execute(job);
} else {
try {
......@@ -183,13 +187,8 @@ public final class Decompiler {
}
void processClass(ClassNode cls) {
try {
ProcessClass job = new ProcessClass(cls, passes);
LOG.info("processing class {} ...", cls);
job.run();
} catch (Throwable e) {
LOG.error("Process class error", e);
}
LOG.info("processing class {} ...", cls);
ProcessClass.process(cls, passes);
}
RootNode getRoot() {
......
......@@ -10,7 +10,7 @@ import jadx.core.dex.visitors.DotGraphVisitor;
import jadx.core.dex.visitors.EnumVisitor;
import jadx.core.dex.visitors.FallbackModeVisitor;
import jadx.core.dex.visitors.IDexTreeVisitor;
import jadx.core.dex.visitors.MethodInlinerVisitor;
import jadx.core.dex.visitors.MethodInlineVisitor;
import jadx.core.dex.visitors.ModVisitor;
import jadx.core.dex.visitors.SimplifyVisitor;
import jadx.core.dex.visitors.regions.CheckRegions;
......@@ -79,7 +79,7 @@ public class Jadx {
passes.add(new DotGraphVisitor(outDir, true));
}
passes.add(new MethodInlinerVisitor());
passes.add(new MethodInlineVisitor());
passes.add(new ClassModifier());
}
passes.add(new CodeGen(args));
......
......@@ -10,19 +10,13 @@ import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class ProcessClass implements Runnable {
public final class ProcessClass {
private static final Logger LOG = LoggerFactory.getLogger(ProcessClass.class);
private final ClassNode cls;
private final List<IDexTreeVisitor> passes;
public ProcessClass(ClassNode cls, List<IDexTreeVisitor> passes) {
this.cls = cls;
this.passes = passes;
private ProcessClass() {
}
@Override
public void run() {
public static void process(ClassNode cls, List<IDexTreeVisitor> passes) {
try {
cls.load();
for (IDexTreeVisitor visitor : passes) {
......@@ -30,6 +24,8 @@ public final class ProcessClass implements Runnable {
}
} catch (DecodeException e) {
LOG.error("Decode exception: " + cls, e);
} catch (Exception e) {
LOG.error("Class process exception: " + cls, e);
} finally {
cls.unload();
}
......
......@@ -76,7 +76,7 @@ public class AnnotationGen {
code.add('@');
code.add(classGen.useClass(a.getType()));
Map<String, Object> vl = a.getValues();
if (vl.size() != 0) {
if (!vl.isEmpty()) {
code.add('(');
if (vl.size() == 1 && vl.containsKey("value")) {
code.add(encValueToString(vl.get("value")));
......
......@@ -379,11 +379,10 @@ public class ClassGen {
if (searchCollision(cls.dex(), useCls, shortName)) {
return clsStr;
}
for (ClassInfo cls : imports) {
if (!cls.equals(classInfo)) {
if (cls.getShortName().equals(shortName)) {
return clsStr;
}
for (ClassInfo importCls : imports) {
if (!importCls.equals(classInfo)
&& importCls.getShortName().equals(shortName)) {
return clsStr;
}
}
addImport(classInfo);
......
......@@ -82,7 +82,7 @@ public class CodeWriter {
attachAnnotation(entry.getKey(), line + entry.getValue());
}
line += code.line;
buf.append(code.toString());
buf.append(code);
return this;
}
......@@ -116,7 +116,7 @@ public class CodeWriter {
return this;
}
private static final String[] INDENT_CACHE = new String[]{
private static final String[] INDENT_CACHE = {
"",
INDENT,
INDENT + INDENT,
......
......@@ -42,7 +42,7 @@ public class ConditionGen {
}
return sb.toString();
default:
return "??" + condition.toString();
return "??" + condition;
}
}
......
......@@ -114,7 +114,7 @@ public class InsnGen {
public String assignVar(InsnNode insn) throws CodegenException {
RegisterArg arg = insn.getResult();
if (insn.getAttributes().contains(AttributeType.DECLARE_VARIABLE)) {
if (insn.getAttributes().contains(AttributeFlag.DECLARE_VAR)) {
return declareVar(arg);
} else {
return arg(arg).toString();
......@@ -125,7 +125,7 @@ public class InsnGen {
return useType(arg.getType()) + " " + mgen.assignArg(arg);
}
private String lit(LiteralArg arg) {
private static String lit(LiteralArg arg) {
return TypeGen.literalToString(arg.getLiteral(), arg.getType());
}
......@@ -483,7 +483,8 @@ public class InsnGen {
if (!elType.equals(insnElementType) && !insnArrayType.equals(ArgType.OBJECT)) {
ErrorsCounter.methodError(mth,
"Incorrect type for fill-array insn " + InsnUtils.formatOffset(insn.getOffset())
+ ", element type: " + elType + ", insn element type: " + insnElementType);
+ ", element type: " + elType + ", insn element type: " + insnElementType
);
if (!elType.isTypeKnown()) {
elType = insnElementType.isTypeKnown() ? insnElementType : elType.selectFirst();
}
......
......@@ -105,7 +105,8 @@ public class MethodGen {
} else {
LOG.warn(ErrorsCounter.formatErrorMsg(mth,
"Incorrect number of args for enum constructor: " + args.size()
+ " (expected >= 2)"));
+ " (expected >= 2)"
));
}
}
code.add(makeArguments(args));
......@@ -269,7 +270,7 @@ public class MethodGen {
code.startLine("*/");
}
private void makeFallbackMethod(CodeWriter code, MethodNode mth) {
private static void makeFallbackMethod(CodeWriter code, MethodNode mth) {
if (mth.getInstructions() == null) {
// loadFile original instructions
try {
......
......@@ -2,19 +2,13 @@ package jadx.core.codegen;
import jadx.core.dex.attributes.AttributeFlag;
import jadx.core.dex.attributes.AttributeType;
import jadx.core.dex.attributes.DeclareVariableAttr;
import jadx.core.dex.attributes.DeclareVariablesAttr;
import jadx.core.dex.attributes.ForceReturnAttr;
import jadx.core.dex.attributes.IAttribute;
import jadx.core.dex.info.FieldInfo;
import jadx.core.dex.instructions.ArithNode;
import jadx.core.dex.instructions.IfOp;
import jadx.core.dex.instructions.IndexInsnNode;
import jadx.core.dex.instructions.InsnType;
import jadx.core.dex.instructions.SwitchNode;
import jadx.core.dex.instructions.args.ArgType;
import jadx.core.dex.instructions.args.InsnArg;
import jadx.core.dex.instructions.args.InsnWrapArg;
import jadx.core.dex.instructions.args.LiteralArg;
import jadx.core.dex.instructions.args.RegisterArg;
import jadx.core.dex.nodes.BlockNode;
import jadx.core.dex.nodes.IBlock;
......@@ -22,7 +16,6 @@ import jadx.core.dex.nodes.IContainer;
import jadx.core.dex.nodes.IRegion;
import jadx.core.dex.nodes.InsnNode;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.dex.regions.Compare;
import jadx.core.dex.regions.IfCondition;
import jadx.core.dex.regions.IfRegion;
import jadx.core.dex.regions.LoopRegion;
......@@ -32,7 +25,6 @@ import jadx.core.dex.regions.SynchronizedRegion;
import jadx.core.dex.trycatch.CatchAttr;
import jadx.core.dex.trycatch.ExceptionHandler;
import jadx.core.dex.trycatch.TryCatchBlock;
import jadx.core.utils.ErrorsCounter;
import jadx.core.utils.RegionUtils;
import jadx.core.utils.exceptions.CodegenException;
......@@ -49,22 +41,12 @@ public class RegionGen extends InsnGen {
}
public void makeRegion(CodeWriter code, IContainer cont) throws CodegenException {
assert cont != null;
if (cont instanceof IBlock) {
makeSimpleBlock((IBlock) cont, code);
} else if (cont instanceof IRegion) {
declareVars(code, cont);
if (cont instanceof Region) {
Region r = (Region) cont;
CatchAttr tc = (CatchAttr) r.getAttributes().get(AttributeType.CATCH_BLOCK);
if (tc != null) {
makeTryCatch(cont, tc.getTryBlock(), code);
} else {
for (IContainer c : r.getSubBlocks()) {
makeRegion(code, c);
}
}
makeSimpleRegion(code, (Region) cont);
} else if (cont instanceof IfRegion) {
makeIf((IfRegion) cont, code, true);
} else if (cont instanceof SwitchRegion) {
......@@ -75,13 +57,13 @@ public class RegionGen extends InsnGen {
makeSynchronizedRegion((SynchronizedRegion) cont, code);
}
} else {
throw new CodegenException("Not processed container: " + cont.toString());
throw new CodegenException("Not processed container: " + cont);
}
}
private void declareVars(CodeWriter code, IContainer cont) {
DeclareVariableAttr declVars =
(DeclareVariableAttr) cont.getAttributes().get(AttributeType.DECLARE_VARIABLE);
DeclareVariablesAttr declVars =
(DeclareVariablesAttr) cont.getAttributes().get(AttributeType.DECLARE_VARIABLES);
if (declVars != null) {
for (RegisterArg v : declVars.getVars()) {
code.startLine(declareVar(v)).add(';');
......@@ -89,6 +71,17 @@ public class RegionGen extends InsnGen {
}
}
private void makeSimpleRegion(CodeWriter code, Region region) throws CodegenException {
CatchAttr tc = (CatchAttr) region.getAttributes().get(AttributeType.CATCH_BLOCK);
if (tc != null) {
makeTryCatch(region, tc.getTryBlock(), code);
} else {
for (IContainer c : region.getSubBlocks()) {
makeRegion(code, c);
}
}
}
public void makeRegionIndent(CodeWriter code, IContainer region) throws CodegenException {
code.incIndent();
makeRegion(code, region);
......@@ -125,26 +118,33 @@ public class RegionGen extends InsnGen {
IContainer els = region.getElseRegion();
if (els != null && RegionUtils.notEmpty(els)) {
code.add(" else ");
// connect if-else-if block
if (els instanceof Region) {
Region re = (Region) els;
List<IContainer> subBlocks = re.getSubBlocks();
if (subBlocks.size() == 1 && subBlocks.get(0) instanceof IfRegion) {
IfRegion ifRegion = (IfRegion) subBlocks.get(0);
if (ifRegion.getAttributes().contains(AttributeFlag.ELSE_IF_CHAIN)) {
makeIf(ifRegion, code, false);
return;
}
}
if (connectElseIf(code, els)) {
return;
}
code.add('{');
makeRegionIndent(code, els);
code.startLine('}');
}
}
/**
* Connect if-else-if block
*/
private boolean connectElseIf(CodeWriter code, IContainer els) throws CodegenException {
if (els instanceof Region) {
Region re = (Region) els;
List<IContainer> subBlocks = re.getSubBlocks();
if (subBlocks.size() == 1 && subBlocks.get(0) instanceof IfRegion) {
IfRegion ifRegion = (IfRegion) subBlocks.get(0);
if (ifRegion.getAttributes().contains(AttributeFlag.ELSE_IF_CHAIN)) {
makeIf(ifRegion, code, false);
return true;
}
}
}
return false;
}
private CodeWriter makeLoop(LoopRegion region, CodeWriter code) throws CodegenException {
BlockNode header = region.getHeader();
if (header != null) {
......@@ -152,7 +152,8 @@ public class RegionGen extends InsnGen {
if (headerInsns.size() > 1) {
// write not inlined instructions from header
mth.getAttributes().add(AttributeFlag.INCONSISTENT_CODE);
for (int i = 0; i < headerInsns.size() - 1; i++) {
int last = headerInsns.size() - 1;
for (int i = 0; i < last; i++) {
InsnNode insn = headerInsns.get(i);
makeInsn(insn, code);
}
......@@ -187,75 +188,6 @@ public class RegionGen extends InsnGen {
code.startLine('}');
}
private String makeCondition(IfCondition condition) throws CodegenException {
switch (condition.getMode()) {
case COMPARE:
return makeCompare(condition.getCompare());
case NOT:
return "!" + makeCondition(condition.getArgs().get(0));
case AND:
case OR:
String mode = condition.getMode() == IfCondition.Mode.AND ? " && " : " || ";
StringBuilder sb = new StringBuilder();
for (IfCondition arg : condition.getArgs()) {
if (sb.length() != 0) {
sb.append(mode);
}
String s = makeCondition(arg);
if (arg.isCompare()) {
sb.append(s);
} else {
sb.append('(').append(s).append(')');
}
}
return sb.toString();
default:
return "??" + condition.toString();
}
}
private String makeCompare(Compare compare) throws CodegenException {
IfOp op = compare.getOp();
InsnArg firstArg = compare.getA();
InsnArg secondArg = compare.getB();
if (firstArg.getType().equals(ArgType.BOOLEAN)
&& secondArg.isLiteral()
&& secondArg.getType().equals(ArgType.BOOLEAN)) {
LiteralArg lit = (LiteralArg) secondArg;
if (lit.getLiteral() == 0) {
op = op.invert();
}
if (op == IfOp.EQ) {
return arg(firstArg, false).toString(); // == true
} else if (op == IfOp.NE) {
return "!" + arg(firstArg); // != true
}
LOG.warn(ErrorsCounter.formatErrorMsg(mth, "Unsupported boolean condition " + op.getSymbol()));
}
return arg(firstArg, isWrapNeeded(firstArg))
+ " " + op.getSymbol() + " "
+ arg(secondArg, isWrapNeeded(secondArg));
}
private boolean isWrapNeeded(InsnArg arg) {
if (!arg.isInsnWrap()) {
return false;
}
InsnNode insn = ((InsnWrapArg) arg).getWrapInsn();
if (insn.getType() == InsnType.ARITH) {
ArithNode arith = ((ArithNode) insn);
switch (arith.getOp()) {
case ADD:
case SUB:
case MUL:
case DIV:
case REM:
return false;
}
}
return true;
}
private CodeWriter makeSwitch(SwitchRegion sw, CodeWriter code) throws CodegenException {
SwitchNode insn = (SwitchNode) sw.getHeader().getInstructions().get(0);
InsnArg arg = insn.getArg(0);
......@@ -324,7 +256,7 @@ public class RegionGen extends InsnGen {
private void makeCatchBlock(CodeWriter code, ExceptionHandler handler)
throws CodegenException {
IContainer region = handler.getHandlerRegion();
if (region != null /* && RegionUtils.notEmpty(region) */) {
if (region != null) {
code.startLine("} catch (");
code.add(handler.isCatchAll() ? "Throwable" : useClass(handler.getCatchType()));
code.add(' ');
......
......@@ -61,7 +61,8 @@ public class NameMapper {
"void",
"volatile",
"while",
}));
})
);
public static boolean isReserved(String str) {
return RESERVED_NAMES.contains(str);
......
......@@ -12,6 +12,8 @@ public enum AttributeFlag {
BREAK,
RETURN, // block contains only return instruction
DECLARE_VAR,
DONT_SHRINK,
DONT_GENERATE,
SKIP,
......
......@@ -27,7 +27,8 @@ public enum AttributeType {
SOURCE_FILE(true),
DECLARE_VARIABLE(true);
// for regions
DECLARE_VARIABLES(true);
private static final int NOT_UNIQ_COUNT;
private final boolean uniq;
......
......@@ -48,7 +48,7 @@ public final class BlockRegState {
if (str.length() != 0) {
str.append(", ");
}
str.append(reg.toString());
str.append(reg);
}
}
return str.toString();
......
......@@ -3,37 +3,27 @@ package jadx.core.dex.attributes;
import jadx.core.dex.instructions.args.RegisterArg;
import jadx.core.utils.Utils;
import java.util.LinkedList;
import java.util.List;
public class DeclareVariableAttr implements IAttribute {
/**
* List of variables to be declared at region start.
*/
public class DeclareVariablesAttr implements IAttribute {
private final List<RegisterArg> vars;
private final List<RegisterArg> vars = new LinkedList<RegisterArg>();
public DeclareVariableAttr() {
this.vars = null; // for instruction use result
}
public DeclareVariableAttr(List<RegisterArg> vars) {
this.vars = vars; // for regions
}
public List<RegisterArg> getVars() {
public Iterable<RegisterArg> getVars() {
return vars;
}
public void addVar(RegisterArg arg) {
int i;
if ((i = vars.indexOf(arg)) != -1) {
if (vars.get(i).getType().equals(arg.getType())) {
return;
}
}
vars.add(arg);
}
@Override
public AttributeType getType() {
return AttributeType.DECLARE_VARIABLE;
return AttributeType.DECLARE_VARIABLES;
}
@Override
......
......@@ -26,7 +26,7 @@ public class JadxErrorAttr implements IAttribute {
if (cause == null) {
str.append("null");
} else {
str.append(cause.getClass().toString());
str.append(cause.getClass());
str.append(":");
str.append(cause.getMessage());
str.append("\n");
......
......@@ -32,11 +32,7 @@ public class JumpAttribute implements IAttribute {
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + dest;
result = prime * result + src;
return result;
return 31 * dest + src;
}
@Override
......
......@@ -58,37 +58,37 @@ public final class ClassInfo {
String fullObjectName = type.getObject();
assert fullObjectName.indexOf('/') == -1 : "Raw type: " + type;
String name;
String clsName;
int dot = fullObjectName.lastIndexOf('.');
if (dot == -1) {
// rename default package if it used from class with package (often for obfuscated apps),
pkg = Consts.DEFAULT_PACKAGE_NAME;
name = fullObjectName;
clsName = fullObjectName;
} else {
pkg = fullObjectName.substring(0, dot);
name = fullObjectName.substring(dot + 1);
clsName = fullObjectName.substring(dot + 1);
}
int sep = name.lastIndexOf('$');
if (canBeInner && sep > 0 && sep != name.length() - 1) {
String parClsName = pkg + '.' + name.substring(0, sep);
int sep = clsName.lastIndexOf('$');
if (canBeInner && sep > 0 && sep != clsName.length() - 1) {
String parClsName = pkg + '.' + clsName.substring(0, sep);
parentClass = fromName(parClsName);
name = name.substring(sep + 1);
clsName = clsName.substring(sep + 1);
} else {
parentClass = null;
}
char firstChar = name.charAt(0);
char firstChar = clsName.charAt(0);
if (Character.isDigit(firstChar)) {
name = Consts.ANONYMOUS_CLASS_PREFIX + name;
clsName = Consts.ANONYMOUS_CLASS_PREFIX + clsName;
} else if (firstChar == '$') {
name = "_" + name;
clsName = "_" + clsName;
}
if (NameMapper.isReserved(name)) {
name += "_";
if (NameMapper.isReserved(clsName)) {
clsName += "_";
}
this.fullName = (parentClass != null ? parentClass.getFullName() : pkg) + "." + name;
this.name = name;
this.fullName = (parentClass != null ? parentClass.getFullName() : pkg) + "." + clsName;
this.name = clsName;
}
public String getFullPath() {
......
......@@ -88,11 +88,9 @@ public final class MethodInfo {
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + declClass.hashCode();
result = prime * result + retType.hashCode();
result = prime * result + shortId.hashCode();
int result = declClass.hashCode();
result = 31 * result + retType.hashCode();
result = 31 * result + shortId.hashCode();
return result;
}
......
......@@ -229,7 +229,7 @@ public abstract class ArgType {
@Override
public String toString() {
return arrayElement.toString() + "[]";
return arrayElement + "[]";
}
}
......
......@@ -88,7 +88,7 @@ public class RegisterArg extends InsnArg {
public boolean isThis() {
if (isRegister()) {
String name = getTypedVar().getName();
if (name != null && name.equals("this")) {
if ("this".equals(name)) {
return true;
}
// maybe it was moved from 'this' register
......@@ -120,13 +120,7 @@ public class RegisterArg extends InsnArg {
return false;
}
RegisterArg other = (RegisterArg) obj;
if (regNum != other.regNum) {
return false;
}
if (!typedVar.equals(other.typedVar)) {
return false;
}
return true;
return regNum == other.regNum && typedVar.equals(other.typedVar);
}
@Override
......
......@@ -51,9 +51,9 @@ public class TypedVar {
}
public void mergeName(TypedVar arg) {
String name = arg.getName();
if (name != null) {
setName(name);
String argName = arg.getName();
if (argName != null) {
setName(argName);
} else if (getName() != null) {
arg.setName(getName());
}
......
......@@ -124,7 +124,7 @@ public class ClassNode extends LineAttrNode implements ILoadable {
int offset = cls.getAnnotationsOffset();
if (offset != 0) {
try {
new AnnotationsParser(this, offset);
new AnnotationsParser(this).parse(offset);
} catch (DecodeException e) {
LOG.error("Error parsing annotations in " + this, e);
}
......
......@@ -91,13 +91,11 @@ public class InsnNode extends LineAttrNode {
InsnArg arg = arguments.get(i);
if (arg == from) {
// TODO correct remove from use list
// from.getTypedVar().getUseList().remove(from);
setArg(i, to);
return true;
} else if (arg.isInsnWrap()) {
if (((InsnWrapArg) arg).getWrapInsn().replaceArg(from, to)) {
return true;
}
}
if (arg.isInsnWrap() && ((InsnWrapArg) arg).getWrapInsn().replaceArg(from, to)) {
return true;
}
}
return false;
......
......@@ -47,7 +47,7 @@ public class RootNode {
initInnerClasses(classes);
}
private void initClassPath(List<ClassNode> classes) throws IOException, DecodeException {
private static void initClassPath(List<ClassNode> classes) throws IOException, DecodeException {
ClspGraph clsp = new ClspGraph();
clsp.load();
clsp.addApp(classes);
......
......@@ -4,6 +4,7 @@ import jadx.core.dex.attributes.annotations.Annotation;
import jadx.core.dex.attributes.annotations.Annotation.Visibility;
import jadx.core.dex.attributes.annotations.AnnotationsList;
import jadx.core.dex.attributes.annotations.MethodParameters;
import jadx.core.dex.instructions.args.ArgType;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.DexNode;
import jadx.core.dex.nodes.FieldNode;
......@@ -20,9 +21,14 @@ import com.android.dx.io.DexBuffer.Section;
public class AnnotationsParser {
private final DexNode dex;
private final ClassNode cls;
public AnnotationsParser(ClassNode cls, int offset) throws DecodeException {
public AnnotationsParser(ClassNode cls) {
this.cls = cls;
this.dex = cls.dex();
}
public void parse(int offset) throws DecodeException {
Section section = dex.openSection(offset);
// TODO read as unsigned int
......@@ -70,10 +76,10 @@ public class AnnotationsParser {
return new AnnotationsList(list);
}
private static final Annotation.Visibility[] VISIBILITIES = new Annotation.Visibility[]{
Annotation.Visibility.BUILD,
Annotation.Visibility.RUNTIME,
Annotation.Visibility.SYSTEM
private static final Annotation.Visibility[] VISIBILITIES = {
Visibility.BUILD,
Visibility.RUNTIME,
Visibility.SYSTEM
};
public static Annotation readAnnotation(DexNode dex, Section s, boolean readVisibility) throws DecodeException {
......@@ -89,6 +95,11 @@ public class AnnotationsParser {
String name = dex.getString(s.readUleb128());
values.put(name, parser.parseValue());
}
return new Annotation(visibility, dex.getType(typeIndex), values);
ArgType type = dex.getType(typeIndex);
Annotation annotation = new Annotation(visibility, type, values);
if (!type.isObject()) {
throw new DecodeException("Incorrect type for annotation: " + annotation);
}
return annotation;
}
}
......@@ -25,9 +25,12 @@ public class DebugInfoParser {
private static final int DBG_SET_EPILOGUE_BEGIN = 0x08;
private static final int DBG_SET_FILE = 0x09;
private static final int DBG_FIRST_SPECIAL = 0x0a; // the smallest special opcode
private static final int DBG_LINE_BASE = -4; // the smallest line number increment
private static final int DBG_LINE_RANGE = 15; // the number of line increments represented
// the smallest special opcode
private static final int DBG_FIRST_SPECIAL = 0x0a;
// the smallest line number increment
private static final int DBG_LINE_BASE = -4;
// the number of line increments represented
private static final int DBG_LINE_RANGE = 15;
private final MethodNode mth;
private final Section section;
......@@ -42,8 +45,9 @@ public class DebugInfoParser {
this.dex = mth.dex();
this.section = dex.openSection(debugOffset);
this.locals = new LocalVar[mth.getRegsCount()];
this.activeRegisters = new InsnArg[mth.getRegsCount()];
int regsCount = mth.getRegsCount();
this.locals = new LocalVar[regsCount];
this.activeRegisters = new InsnArg[regsCount];
this.insnByOffset = insnByOffset;
}
......@@ -51,7 +55,7 @@ public class DebugInfoParser {
int addr = 0;
int line = section.readUleb128();
int paramsCount = section.readUleb128(); // exclude 'this'
int paramsCount = section.readUleb128();
List<RegisterArg> mthArgs = mth.getArguments(false);
assert paramsCount == mthArgs.size();
......@@ -69,7 +73,8 @@ public class DebugInfoParser {
activeRegisters[rn] = arg;
}
addrChange(-1, 1, line); // process '0' instruction
// process '0' instruction
addrChange(-1, 1, line);
int c = section.readByte() & 0xFF;
while (c != DBG_END_SEQUENCE) {
......@@ -139,7 +144,7 @@ public class DebugInfoParser {
if (c >= DBG_FIRST_SPECIAL) {
int adjustedOpcode = c - DBG_FIRST_SPECIAL;
line += DBG_LINE_BASE + (adjustedOpcode % DBG_LINE_RANGE);
int addrInc = (adjustedOpcode / DBG_LINE_RANGE);
int addrInc = adjustedOpcode / DBG_LINE_RANGE;
addr = addrChange(addr, addrInc, line);
} else {
throw new DecodeException("Unknown debug insn code: " + c);
......@@ -213,10 +218,10 @@ public class DebugInfoParser {
}
private static void merge(InsnArg arg, LocalVar var) {
if (arg != null && arg.isRegister()) {
if (var.getRegNum() == ((RegisterArg) arg).getRegNum()) {
arg.mergeDebugInfo(var);
}
if (arg != null
&& arg.isRegister()
&& var.getRegNum() == ((RegisterArg) arg).getRegNum()) {
arg.mergeDebugInfo(var);
}
}
}
......@@ -15,9 +15,9 @@ public final class LoopRegion extends AbstractRegion {
// loop header contains one 'if' insn, equals null for infinite loop
private IfCondition condition;
private BlockNode conditionBlock;
private final BlockNode conditionBlock;
// instruction which must be executed before condition in every loop
private BlockNode preCondition = null;
private BlockNode preCondition;
private IContainer body;
private final boolean conditionAtEnd;
......
......@@ -9,7 +9,7 @@ import java.util.Collections;
import java.util.List;
public final class TernaryRegion extends AbstractRegion {
private IBlock container;
private final IBlock container;
public TernaryRegion(IRegion parent, BlockNode block) {
super(parent);
......
......@@ -17,10 +17,12 @@ import jadx.core.dex.nodes.MethodNode;
import jadx.core.dex.trycatch.CatchAttr;
import jadx.core.dex.trycatch.ExceptionHandler;
import jadx.core.dex.trycatch.SplitterBlockAttr;
import jadx.core.utils.BlockUtils;
import jadx.core.utils.exceptions.JadxRuntimeException;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Iterator;
......@@ -223,7 +225,7 @@ public class BlockMakerVisitor extends AbstractVisitor {
}
private static void computeDominators(MethodNode mth) {
List<BlockNode> basicBlocks = mth.getBasicBlocks();
List<BlockNode> basicBlocks = Collections.unmodifiableList(mth.getBasicBlocks());
int nBlocks = basicBlocks.size();
for (int i = 0; i < nBlocks; i++) {
BlockNode block = basicBlocks.get(i);
......@@ -245,13 +247,15 @@ public class BlockMakerVisitor extends AbstractVisitor {
continue;
}
BitSet d = block.getDoms();
dset.clear();
dset.or(d);
if (!changed) {
dset.clear();
dset.or(d);
}
for (BlockNode pred : block.getPredecessors()) {
d.and(pred.getDoms());
}
d.set(block.getId());
if (!d.equals(dset)) {
if (!changed && !d.equals(dset)) {
changed = true;
}
}
......@@ -315,12 +319,9 @@ public class BlockMakerVisitor extends AbstractVisitor {
private static void markReturnBlocks(MethodNode mth) {
mth.getExitBlocks().clear();
for (BlockNode block : mth.getBasicBlocks()) {
List<InsnNode> insns = block.getInstructions();
if (insns.size() == 1) {
if (insns.get(0).getType() == InsnType.RETURN) {
block.getAttributes().add(AttributeFlag.RETURN);
mth.getExitBlocks().add(block);
}
if (BlockUtils.lastInsnType(block, InsnType.RETURN)) {
block.getAttributes().add(AttributeFlag.RETURN);
mth.getExitBlocks().add(block);
}
}
}
......
......@@ -111,11 +111,9 @@ public class ClassModifier extends AbstractVisitor {
AccessInfo af = mth.getAccessFlags();
// remove bridge methods
if (af.isBridge() && af.isSynthetic()) {
if (!isMethodUniq(cls, mth)) {
// TODO add more checks before method deletion
it.remove();
}
if (af.isBridge() && af.isSynthetic() && !isMethodUniq(cls, mth)) {
// TODO add more checks before method deletion
it.remove();
}
// remove synthetic constructor for inner non-static classes
......@@ -135,11 +133,11 @@ public class ClassModifier extends AbstractVisitor {
private static boolean isMethodUniq(ClassNode cls, MethodNode mth) {
MethodInfo mi = mth.getMethodInfo();
for (MethodNode otherMth : cls.getMethods()) {
MethodInfo omi = otherMth.getMethodInfo();
if (omi.getName().equals(mi.getName())
&& otherMth != mth) {
if (omi.getArgumentsTypes().size() == mi.getArgumentsTypes().size()) {
// TODO: check to args objects types
if (otherMth != mth) {
MethodInfo omi = otherMth.getMethodInfo();
if (omi.getName().equals(mi.getName())
&& omi.getArgumentsTypes().size() == mi.getArgumentsTypes().size()) {
// TODO: check objects types
return false;
}
}
......
......@@ -231,10 +231,8 @@ public class CodeShrinker extends AbstractVisitor {
List<RegisterArg> args = ArgsInfo.getArgs(assignInsn);
boolean startCheck = false;
for (InsnNode insn : assignBlock.getInstructions()) {
if (startCheck) {
if (!insn.canReorder() || ArgsInfo.usedArgAssign(insn, args)) {
return false;
}
if (startCheck && (!insn.canReorder() || ArgsInfo.usedArgAssign(insn, args))) {
return false;
}
if (insn == assignInsn) {
startCheck = true;
......
......@@ -116,11 +116,10 @@ public class ConstInlinerVisitor extends AbstractVisitor {
break;
case IPUT:
case SPUT: {
case SPUT:
IndexInsnNode node = (IndexInsnNode) insn;
insn.getArg(0).merge(((FieldInfo) node.getIndex()).getType());
break;
}
case IF: {
InsnArg arg0 = insn.getArg(0);
......@@ -133,7 +132,7 @@ public class ConstInlinerVisitor extends AbstractVisitor {
break;
}
case CMP_G:
case CMP_L: {
case CMP_L:
InsnArg arg0 = insn.getArg(0);
InsnArg arg1 = insn.getArg(1);
if (arg0 == litArg) {
......@@ -142,7 +141,6 @@ public class ConstInlinerVisitor extends AbstractVisitor {
arg1.merge(arg0);
}
break;
}
case RETURN:
if (insn.getArgsCount() != 0) {
......
......@@ -9,7 +9,6 @@ import jadx.core.dex.nodes.IRegion;
import jadx.core.dex.nodes.InsnNode;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.dex.trycatch.ExceptionHandler;
import jadx.core.utils.BlockUtils;
import jadx.core.utils.InsnUtils;
import jadx.core.utils.Utils;
......@@ -94,7 +93,7 @@ public class DotGraphVisitor extends AbstractVisitor {
IRegion r = (IRegion) region;
String attrs = attributesString(r);
dot.startLine("subgraph " + makeName(region) + " {");
dot.startLine("label = \"" + r.toString()
dot.startLine("label = \"" + r
+ (attrs.length() == 0 ? "" : " | " + attrs)
+ "\";");
dot.startLine("node [shape=record,color=blue];");
......@@ -136,12 +135,6 @@ public class DotGraphVisitor extends AbstractVisitor {
for (BlockNode next : block.getDominatesOn()) {
conn.startLine(makeName(block) + " -> " + makeName(next) + "[style=dotted];");
}
// add all dominators connections
if (false) {
for (BlockNode next : BlockUtils.bitsetToBlocks(mth, block.getDoms())) {
conn.startLine(makeName(block) + " -> " + makeName(next) + "[style=dotted, color=green];");
}
}
}
private String attributesString(IAttributeNode block) {
......@@ -152,7 +145,7 @@ public class DotGraphVisitor extends AbstractVisitor {
return attrs.toString();
}
private String makeName(IContainer c) {
private static String makeName(IContainer c) {
String name;
if (c instanceof BlockNode) {
name = "Node_" + ((BlockNode) c).getId();
......@@ -166,7 +159,7 @@ public class DotGraphVisitor extends AbstractVisitor {
if (rawInsn) {
StringBuilder str = new StringBuilder();
for (InsnNode insn : block.getInstructions()) {
str.append(escape(insn.toString() + " " + insn.getAttributes()));
str.append(escape(insn + " " + insn.getAttributes()));
str.append(NL);
}
return str.toString();
......@@ -181,7 +174,7 @@ public class DotGraphVisitor extends AbstractVisitor {
}
}
private String escape(String string) {
private static String escape(String string) {
return string
.replace("\\", "") // TODO replace \"
.replace("/", "\\/")
......
......@@ -10,17 +10,20 @@ import jadx.core.dex.nodes.InsnNode;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.utils.exceptions.JadxException;
public class MethodInlinerVisitor extends AbstractVisitor {
/**
* Inline synthetic methods.
*/
public class MethodInlineVisitor extends AbstractVisitor {
@Override
public void visit(MethodNode mth) throws JadxException {
AccessInfo accessFlags = mth.getAccessFlags();
if (accessFlags.isSynthetic() && accessFlags.isStatic()) {
if (mth.getBasicBlocks().size() == 2) {
BlockNode block = mth.getBasicBlocks().get(1);
if (block.getAttributes().contains(AttributeFlag.RETURN)) {
inlineMth(mth);
}
if (accessFlags.isSynthetic()
&& accessFlags.isStatic()
&& mth.getBasicBlocks().size() == 2) {
BlockNode block = mth.getBasicBlocks().get(1);
if (block.getAttributes().contains(AttributeFlag.RETURN)) {
inlineMth(mth);
}
}
}
......
......@@ -51,7 +51,7 @@ public class ModVisitor extends AbstractVisitor {
}
}
private void replaceStep(MethodNode mth) {
private static void replaceStep(MethodNode mth) {
ClassNode parentClass = mth.getParentClass();
for (BlockNode block : mth.getBasicBlocks()) {
InstructionRemover remover = new InstructionRemover(block.getInstructions());
......@@ -147,7 +147,7 @@ public class ModVisitor extends AbstractVisitor {
/**
* Remove unnecessary instructions
*/
private void removeStep(MethodNode mth) {
private static void removeStep(MethodNode mth) {
for (BlockNode block : mth.getBasicBlocks()) {
InstructionRemover remover = new InstructionRemover(block.getInstructions());
......@@ -193,7 +193,7 @@ public class ModVisitor extends AbstractVisitor {
}
}
private void processExceptionHander(MethodNode mth, BlockNode block) {
private static void processExceptionHander(MethodNode mth, BlockNode block) {
ExcHandlerAttr handlerAttr = (ExcHandlerAttr) block.getAttributes().get(AttributeType.EXC_HANDLER);
if (handlerAttr == null) {
return;
......@@ -252,7 +252,7 @@ public class ModVisitor extends AbstractVisitor {
block.getInstructions().set(i, insn);
}
private void checkArgsNames(MethodNode mth) {
private static void checkArgsNames(MethodNode mth) {
for (RegisterArg arg : mth.getArguments(false)) {
String name = arg.getTypedVar().getName();
if (name != null && NameMapper.isReserved(name)) {
......
package jadx.core.dex.visitors.regions;
import jadx.core.Consts;
import jadx.core.dex.attributes.AttributeFlag;
import jadx.core.dex.nodes.BlockNode;
import jadx.core.dex.nodes.IBlock;
......@@ -33,7 +32,6 @@ public class CheckRegions extends AbstractVisitor {
public void processBlock(MethodNode mth, IBlock container) {
if (container instanceof BlockNode) {
blocksInRegions.add((BlockNode) container);
}
}
};
......@@ -41,16 +39,11 @@ public class CheckRegions extends AbstractVisitor {
if (mth.getBasicBlocks().size() != blocksInRegions.size()) {
for (BlockNode block : mth.getBasicBlocks()) {
if (!blocksInRegions.contains(block)) {
if (!block.getInstructions().isEmpty()
&& !block.getAttributes().contains(AttributeFlag.SKIP)) {
mth.getAttributes().add(AttributeFlag.INCONSISTENT_CODE);
if (Consts.DEBUG) {
LOG.debug(" Missing block: {} in {}", block, mth);
} else {
break;
}
}
if (!blocksInRegions.contains(block)
&& !block.getInstructions().isEmpty()
&& !block.getAttributes().contains(AttributeFlag.SKIP)) {
mth.getAttributes().add(AttributeFlag.INCONSISTENT_CODE);
LOG.debug(" Missing block: {} in {}", block, mth);
}
}
}
......
......@@ -69,11 +69,11 @@ public class ProcessTryCatchRegions extends AbstractRegionVisitor {
assert bs != null;
// intersect to get dominator of dominators
List<BlockNode> domBlocks = BlockUtils.bitsetToBlocks(mth, bs);
List<BlockNode> domBlocks = BlockUtils.bitSetToBlocks(mth, bs);
for (BlockNode block : domBlocks) {
bs.andNot(block.getDoms());
}
domBlocks = BlockUtils.bitsetToBlocks(mth, bs);
domBlocks = BlockUtils.bitSetToBlocks(mth, bs);
if (domBlocks.size() != 1) {
throw new JadxRuntimeException(
"Exception block dominator not found, method:" + mth + ". bs: " + bs);
......
package jadx.core.dex.visitors.regions;
import jadx.core.dex.attributes.AttributeFlag;
import jadx.core.dex.attributes.AttributeType;
import jadx.core.dex.attributes.DeclareVariableAttr;
import jadx.core.dex.attributes.DeclareVariablesAttr;
import jadx.core.dex.instructions.args.RegisterArg;
import jadx.core.dex.nodes.IBlock;
import jadx.core.dex.nodes.IContainer;
......@@ -125,7 +126,7 @@ public class ProcessVariables extends AbstractVisitor {
for (IRegion assignRegion : u.getAssigns()) {
if (u.getArgRegion() == assignRegion
&& canDeclareInRegion(u, assignRegion)) {
u.getArg().getParentInsn().getAttributes().add(new DeclareVariableAttr());
u.getArg().getParentInsn().getAttributes().add(AttributeFlag.DECLARE_VAR);
it.remove();
break;
}
......@@ -167,17 +168,16 @@ public class ProcessVariables extends AbstractVisitor {
}
}
private void declareVar(IContainer region, RegisterArg arg) {
DeclareVariableAttr dv =
(DeclareVariableAttr) region.getAttributes().get(AttributeType.DECLARE_VARIABLE);
private static void declareVar(IContainer region, RegisterArg arg) {
DeclareVariablesAttr dv = (DeclareVariablesAttr) region.getAttributes().get(AttributeType.DECLARE_VARIABLES);
if (dv == null) {
dv = new DeclareVariableAttr(new ArrayList<RegisterArg>());
dv = new DeclareVariablesAttr();
region.getAttributes().add(dv);
}
dv.addVar(arg);
}
private boolean canDeclareInRegion(Usage u, IRegion region) {
private static boolean canDeclareInRegion(Usage u, IRegion region) {
for (IRegion r : u.getAssigns()) {
if (!RegionUtils.isRegionContainsRegion(region, r)) {
return false;
......
......@@ -350,7 +350,7 @@ public class RegionMaker {
/**
* Traverse from monitor-enter thru successors and collect blocks contains monitor-exit
*/
private void traverseMonitorExits(InsnArg arg, BlockNode block, Set<BlockNode> exits, Set<BlockNode> visited) {
private static void traverseMonitorExits(InsnArg arg, BlockNode block, Set<BlockNode> exits, Set<BlockNode> visited) {
visited.add(block);
for (InsnNode insn : block.getInstructions()) {
if (insn.getType() == InsnType.MONITOR_EXIT
......@@ -370,7 +370,7 @@ public class RegionMaker {
/**
* Traverse from monitor-enter thru successors and search for exit paths cross
*/
private BlockNode traverseMonitorExitsCross(BlockNode block, Set<BlockNode> exits, Set<BlockNode> visited) {
private static BlockNode traverseMonitorExitsCross(BlockNode block, Set<BlockNode> exits, Set<BlockNode> visited) {
visited.add(block);
for (BlockNode node : block.getCleanSuccessors()) {
boolean cross = true;
......@@ -543,7 +543,7 @@ public class RegionMaker {
return result;
}
private BlockNode getIfNode(BlockNode block) {
private static BlockNode getIfNode(BlockNode block) {
if (block != null && !block.getAttributes().contains(AttributeType.LOOP)) {
List<InsnNode> insns = block.getInstructions();
if (insns.size() == 1 && insns.get(0).getType() == InsnType.IF) {
......@@ -603,7 +603,7 @@ public class RegionMaker {
Map<BlockNode, List<Object>> blocksMap = new LinkedHashMap<BlockNode, List<Object>>(len);
for (Entry<Integer, List<Object>> entry : casesMap.entrySet()) {
BlockNode c = getBlockByOffset((int) entry.getKey(), block.getSuccessors());
BlockNode c = getBlockByOffset(entry.getKey(), block.getSuccessors());
assert c != null;
blocksMap.put(c, entry.getValue());
}
......@@ -648,7 +648,7 @@ public class RegionMaker {
if (out != null) {
stack.addExit(out);
} else {
for (BlockNode e : BlockUtils.bitsetToBlocks(mth, domsOn)) {
for (BlockNode e : BlockUtils.bitSetToBlocks(mth, domsOn)) {
stack.addExit(e);
}
}
......@@ -689,7 +689,7 @@ public class RegionMaker {
handler.getHandlerRegion().getAttributes().add(excHandlerAttr);
}
private boolean isEqualReturns(BlockNode b1, BlockNode b2) {
private static boolean isEqualReturns(BlockNode b1, BlockNode b2) {
if (b1 == b2) {
return true;
}
......
......@@ -18,7 +18,7 @@ public abstract class TracedRegionVisitor implements IRegionVisitor {
@Override
public void processBlock(MethodNode mth, IBlock container) {
final IRegion curRegion = regionStack.peek();
IRegion curRegion = regionStack.peek();
processBlockTraced(mth, container, curRegion);
}
......
......@@ -2,6 +2,7 @@ package jadx.core.dex.visitors.typeresolver;
import jadx.core.dex.attributes.BlockRegState;
import jadx.core.dex.instructions.IndexInsnNode;
import jadx.core.dex.instructions.InsnType;
import jadx.core.dex.instructions.args.ArgType;
import jadx.core.dex.instructions.args.InsnArg;
import jadx.core.dex.instructions.args.RegisterArg;
......@@ -34,20 +35,18 @@ public class TypeResolver extends AbstractVisitor {
/**
* Check argument types (can be broken after merging debug info)
*/
private void prepare(MethodNode mth) {
private static void prepare(MethodNode mth) {
for (BlockNode block : mth.getBasicBlocks()) {
for (InsnNode insn : block.getInstructions()) {
switch (insn.getType()) {
case CHECK_CAST:
ArgType castType = (ArgType) ((IndexInsnNode) insn).getIndex();
insn.getResult().getTypedVar().forceSetType(castType);
break;
if (insn.getType() == InsnType.CHECK_CAST) {
ArgType castType = (ArgType) ((IndexInsnNode) insn).getIndex();
insn.getResult().getTypedVar().forceSetType(castType);
}
}
}
}
private void visitBlocks(MethodNode mth) {
private static void visitBlocks(MethodNode mth) {
for (BlockNode block : mth.getBasicBlocks()) {
BlockRegState state = new BlockRegState(mth);
......@@ -94,7 +93,7 @@ public class TypeResolver extends AbstractVisitor {
}
}
private boolean connectEdges(MethodNode mth, BlockNode from, BlockNode to, boolean back) {
private static boolean connectEdges(MethodNode mth, BlockNode from, BlockNode to, boolean back) {
BlockRegState end = from.getEndState();
BlockRegState start = to.getStartState();
......
......@@ -8,11 +8,10 @@ import jadx.core.utils.ErrorsCounter;
public class CheckTypeVisitor {
public static void visit(MethodNode mth, InsnNode insn) {
if (insn.getResult() != null) {
if (!insn.getResult().getType().isTypeKnown()) {
error("Wrong return type", mth, insn);
return;
}
if (insn.getResult() != null
&& !insn.getResult().getType().isTypeKnown()) {
error("Wrong return type", mth, insn);
return;
}
for (InsnArg arg : insn.getArguments()) {
......
......@@ -51,6 +51,9 @@ public class BlockUtils {
}
public static boolean isBackEdge(BlockNode from, BlockNode to) {
if (to == null) {
return false;
}
if (from.getCleanSuccessors().contains(to)) {
return false; // already checked
}
......@@ -69,16 +72,6 @@ public class BlockUtils {
}
}
public static BlockNode canMergeNextBlock(BlockNode block) {
BlockNode next = getNextBlock(block);
if (next != null) {
if (next.getIDom() == block) {
return next;
}
}
return null;
}
/**
* Check if instruction contains in block (use == for comparison, not equals)
*/
......@@ -118,7 +111,7 @@ public class BlockUtils {
return bs;
}
public static List<BlockNode> bitsetToBlocks(MethodNode mth, BitSet bs) {
public static List<BlockNode> bitSetToBlocks(MethodNode mth, BitSet bs) {
List<BlockNode> blocks = new ArrayList<BlockNode>(bs.cardinality());
for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1)) {
BlockNode block = mth.getBasicBlocks().get(i);
......
......@@ -16,7 +16,7 @@ public class ErrorsCounter {
private static final Logger LOG = LoggerFactory.getLogger(ErrorsCounter.class);
private static final Set<Object> ERROR_NODES = new HashSet<Object>();
private static int errorsCount = 0;
private static int errorsCount;
public static int getErrorCount() {
return errorsCount;
......
......@@ -46,7 +46,7 @@ public class InsnUtils {
if (index instanceof String) {
return "\"" + index + "\"";
} else {
return " " + index.toString();
return " " + index;
}
}
}
......@@ -77,7 +77,6 @@ public class RegionUtils {
if (container == region) {
return true;
}
if (container instanceof IRegion) {
IRegion r = (IRegion) container;
......@@ -92,10 +91,9 @@ public class RegionUtils {
return true;
}
}
if (tb.getFinalBlock() != null) {
if (isRegionContainsRegion(tb.getFinalBlock(), region)) {
return true;
}
if (tb.getFinalBlock() != null
&& isRegionContainsRegion(tb.getFinalBlock(), region)) {
return true;
}
}
if (isRegionContainsRegion(b, region)) {
......
package jadx.api;
import jadx.core.Jadx;
import jadx.core.dex.attributes.AttributeFlag;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.dex.visitors.DepthTraverser;
......@@ -19,6 +20,7 @@ import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.fail;
......@@ -65,6 +67,7 @@ public abstract class InternalJadxTest {
for (IDexTreeVisitor visitor : passes) {
DepthTraverser.visit(visitor, cls);
}
assertFalse(cls.getAttributes().contains(AttributeFlag.INCONSISTENT_CODE));
return cls;
} catch (Exception e) {
fail(e.getMessage());
......
package jadx.tests.internal.inline;
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 TestSyntheticInline extends InternalJadxTest {
public static class TestCls {
private int f;
private int func() {
return -1;
}
public class A {
public int getF() {
return f;
}
public void setF(int v) {
f = v;
}
public int callFunc() {
return func();
}
}
}
@Test
public void test() {
ClassNode cls = getClassNode(TestCls.class);
String code = cls.getCode().toString();
System.out.println(code);
assertThat(code, not(containsString("synthetic")));
assertThat(code, not(containsString("access$")));
assertThat(code, not(containsString("x0")));
assertThat(code, containsString("return f;"));
assertThat(code, containsString("return func();"));
assertThat(code, containsString("f = v;"));
}
}
......@@ -45,20 +45,19 @@ public class JClass extends JNode {
if (!loaded) {
cls.decompile();
loaded = true;
updateChilds();
update();
}
}
@Override
public synchronized void updateChilds() {
public synchronized void update() {
removeAllChildren();
if (!loaded) {
add(new TextNode(NLS.str("tree.loading")));
} else {
for (JavaClass javaClass : cls.getInnerClasses()) {
JClass child = new JClass(javaClass, this);
add(child);
child.updateChilds();
JClass innerCls = new JClass(javaClass, this);
add(innerCls);
innerCls.update();
}
for (JavaField f : cls.getFields()) {
add(new JField(f, this));
......
......@@ -27,10 +27,6 @@ public class JField extends JNode {
this.jParent = jClass;
}
@Override
public void updateChilds() {
}
@Override
public JClass getJParent() {
return jParent;
......
......@@ -29,10 +29,6 @@ public class JMethod extends JNode {
this.jParent = jClass;
}
@Override
public void updateChilds() {
}
@Override
public JClass getJParent() {
return jParent;
......
......@@ -16,7 +16,5 @@ public abstract class JNode extends DefaultMutableTreeNode {
public abstract int getLine();
public abstract void updateChilds();
public abstract Icon getIcon();
}
......@@ -25,7 +25,7 @@ public class JPackage extends JNode implements Comparable<JPackage> {
for (JavaClass javaClass : javaClasses) {
classes.add(new JClass(javaClass));
}
updateChilds();
update();
}
public JPackage(String name) {
......@@ -33,15 +33,14 @@ public class JPackage extends JNode implements Comparable<JPackage> {
this.classes = new ArrayList<JClass>(1);
}
@Override
public void updateChilds() {
public void update() {
removeAllChildren();
for (JPackage pkg : innerPackages) {
pkg.updateChilds();
pkg.update();
add(pkg);
}
for (JClass cls : classes) {
cls.updateChilds();
cls.update();
add(cls);
}
}
......
......@@ -27,11 +27,10 @@ public class JRoot extends JNode {
public JRoot(JadxWrapper wrapper) {
this.wrapper = wrapper;
updateChilds();
update();
}
@Override
public void updateChilds() {
public void update() {
removeAllChildren();
if (flatPackages) {
for (JavaPackage pkg : wrapper.getPackages()) {
......@@ -41,7 +40,7 @@ public class JRoot extends JNode {
// build packages hierarchy
List<JPackage> rootPkgs = getHierarchyPackages(wrapper.getPackages());
for (JPackage jPackage : rootPkgs) {
jPackage.updateChilds();
jPackage.update();
add(jPackage);
}
}
......@@ -88,7 +87,7 @@ public class JRoot extends JNode {
}
// use identity set for collect inner packages
Set<JPackage> innerPackages = Collections.newSetFromMap(new IdentityHashMap<JPackage,Boolean>());
Set<JPackage> innerPackages = Collections.newSetFromMap(new IdentityHashMap<JPackage, Boolean>());
for (JPackage pkg : pkgMap.values()) {
innerPackages.addAll(pkg.getInnerPackages());
}
......@@ -131,7 +130,7 @@ public class JRoot extends JNode {
public void setFlatPackages(boolean flatPackages) {
if (this.flatPackages != flatPackages) {
this.flatPackages = flatPackages;
updateChilds();
update();
}
}
......
......@@ -19,10 +19,6 @@ public class TextNode extends JNode {
return 0;
}
@Override
public void updateChilds() {
}
@Override
public Icon getIcon() {
return null;
......
......@@ -67,10 +67,18 @@ public class Utils {
icon = def;
}
OverlayIcon overIcon = new OverlayIcon(icon);
if (af.isFinal()) overIcon.add(ICON_FINAL);
if (af.isStatic()) overIcon.add(ICON_STATIC);
if (af.isAbstract()) overIcon.add(ICON_ABSTRACT);
if (af.isNative()) overIcon.add(ICON_NATIVE);
if (af.isFinal()) {
overIcon.add(ICON_FINAL);
}
if (af.isStatic()) {
overIcon.add(ICON_STATIC);
}
if (af.isAbstract()) {
overIcon.add(ICON_ABSTRACT);
}
if (af.isNative()) {
overIcon.add(ICON_NATIVE);
}
return overIcon;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册