Use chars instead strings, code refactoring
This commit is contained in:
@@ -55,7 +55,7 @@ public class ClassGen {
|
||||
CodeWriter clsCode = new CodeWriter();
|
||||
|
||||
if (!"".equals(cls.getPackage())) {
|
||||
clsCode.add("package ").add(cls.getPackage()).add(";");
|
||||
clsCode.add("package ").add(cls.getPackage()).add(';');
|
||||
clsCode.endl();
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ public class ClassGen {
|
||||
Collections.sort(sortImports);
|
||||
|
||||
for (String imp : sortImports) {
|
||||
clsCode.startLine("import ").add(imp).add(";");
|
||||
clsCode.startLine("import ").add(imp).add(';');
|
||||
}
|
||||
clsCode.endl();
|
||||
|
||||
@@ -165,7 +165,7 @@ public class ClassGen {
|
||||
}
|
||||
|
||||
public void makeClassBody(CodeWriter clsCode) throws CodegenException {
|
||||
clsCode.add("{");
|
||||
clsCode.add('{');
|
||||
CodeWriter mthsCode = makeMethods(clsCode, cls.getMethods());
|
||||
clsCode.add(makeFields(clsCode, cls, cls.getFields()));
|
||||
|
||||
@@ -174,7 +174,7 @@ public class ClassGen {
|
||||
clsCode.add(makeInnerClasses(cls, clsCode.getIndent()));
|
||||
}
|
||||
clsCode.add(mthsCode);
|
||||
clsCode.startLine("}");
|
||||
clsCode.startLine('}');
|
||||
}
|
||||
|
||||
private CodeWriter makeInnerClasses(ClassNode cls2, int indent) throws CodegenException {
|
||||
@@ -190,7 +190,7 @@ public class ClassGen {
|
||||
return innerClsCode;
|
||||
}
|
||||
|
||||
private CodeWriter makeMethods(CodeWriter clsCode, List<MethodNode> mthList) throws CodegenException {
|
||||
private CodeWriter makeMethods(CodeWriter clsCode, List<MethodNode> mthList) {
|
||||
CodeWriter code = new CodeWriter(clsCode.getIndent() + 1);
|
||||
for (Iterator<MethodNode> it = mthList.iterator(); it.hasNext();) {
|
||||
MethodNode mth = it.next();
|
||||
@@ -208,7 +208,7 @@ public class ClassGen {
|
||||
code.add(" default ").add(v);
|
||||
}
|
||||
}
|
||||
code.add(";");
|
||||
code.add(';');
|
||||
} else {
|
||||
if (mth.isNoCode())
|
||||
continue;
|
||||
@@ -217,7 +217,7 @@ public class ClassGen {
|
||||
mthGen.addDefinition(code);
|
||||
code.add(" {");
|
||||
code.add(mthGen.makeInstructions(code.getIndent()));
|
||||
code.startLine("}");
|
||||
code.startLine('}');
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
String msg = ErrorsCounter.methodError(mth, "Method generation error", e);
|
||||
@@ -268,7 +268,7 @@ public class ClassGen {
|
||||
annotationGen.addForField(code, f);
|
||||
code.startLine(f.getAccessFlags().makeString());
|
||||
code.add(TypeGen.translate(this, f.getType()));
|
||||
code.add(" ");
|
||||
code.add(' ');
|
||||
code.add(f.getName());
|
||||
FieldValueAttr fv = (FieldValueAttr) f.getAttributes().get(AttributeType.FIELD_VALUE);
|
||||
if (fv != null) {
|
||||
@@ -279,7 +279,7 @@ public class ClassGen {
|
||||
code.add(annotationGen.encValueToString(fv.getValue()));
|
||||
}
|
||||
}
|
||||
code.add(";");
|
||||
code.add(';');
|
||||
}
|
||||
if (fields.size() != 0)
|
||||
code.endl();
|
||||
@@ -299,7 +299,7 @@ public class ClassGen {
|
||||
if (generics != null) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(baseClass);
|
||||
sb.append("<");
|
||||
sb.append('<');
|
||||
int len = generics.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (i != 0) {
|
||||
@@ -311,7 +311,7 @@ public class ClassGen {
|
||||
else
|
||||
sb.append('?');
|
||||
}
|
||||
sb.append(">");
|
||||
sb.append('>');
|
||||
return sb.toString();
|
||||
} else {
|
||||
return baseClass;
|
||||
|
||||
@@ -13,7 +13,7 @@ public class CodeWriter {
|
||||
private static final int MAX_FILENAME_LENGTH = 128;
|
||||
|
||||
public static final String NL = System.getProperty("line.separator");
|
||||
public static final String INDENT = "\t";
|
||||
private static final String INDENT = "\t";
|
||||
|
||||
private StringBuilder buf = new StringBuilder();
|
||||
private String indentStr;
|
||||
|
||||
@@ -84,20 +84,15 @@ public class InsnGen {
|
||||
}
|
||||
|
||||
public String assignVar(InsnNode insn) {
|
||||
try {
|
||||
RegisterArg arg = insn.getResult();
|
||||
if (insn.getAttributes().contains(AttributeType.DECLARE_VARIABLE)) {
|
||||
return declareVar(arg);
|
||||
} else {
|
||||
return mgen.makeArgName(arg);
|
||||
}
|
||||
} catch (CodegenException e) {
|
||||
LOG.error("Assign var codegen error", e);
|
||||
return "<error>";
|
||||
RegisterArg arg = insn.getResult();
|
||||
if (insn.getAttributes().contains(AttributeType.DECLARE_VARIABLE)) {
|
||||
return declareVar(arg);
|
||||
} else {
|
||||
return mgen.makeArgName(arg);
|
||||
}
|
||||
}
|
||||
|
||||
public String declareVar(RegisterArg arg) throws CodegenException {
|
||||
public String declareVar(RegisterArg arg) {
|
||||
return useType(arg.getType()) + " " + mgen.assignArg(arg);
|
||||
}
|
||||
|
||||
@@ -237,8 +232,8 @@ public class InsnGen {
|
||||
break;
|
||||
|
||||
case INSTANCE_OF:
|
||||
code.add("(").add(arg(insn, 0)).add(" instanceof ")
|
||||
.add(useType((ArgType) ((IndexInsnNode) insn).getIndex())).add(")");
|
||||
code.add('(').add(arg(insn, 0)).add(" instanceof ")
|
||||
.add(useType((ArgType) ((IndexInsnNode) insn).getIndex())).add(')');
|
||||
break;
|
||||
|
||||
case CONSTRUCTOR:
|
||||
@@ -296,7 +291,7 @@ public class InsnGen {
|
||||
|
||||
case MONITOR_ENTER:
|
||||
if (isFallback()) {
|
||||
code.add("monitor-enter(").add(arg(insn.getArg(0))).add(")");
|
||||
code.add("monitor-enter(").add(arg(insn.getArg(0))).add(')');
|
||||
} else {
|
||||
state.add(InsnGenState.SKIP);
|
||||
}
|
||||
@@ -304,7 +299,7 @@ public class InsnGen {
|
||||
|
||||
case MONITOR_EXIT:
|
||||
if (isFallback()) {
|
||||
code.add("monitor-exit(").add(arg(insn.getArg(0))).add(")");
|
||||
code.add("monitor-exit(").add(arg(insn.getArg(0))).add(')');
|
||||
} else {
|
||||
state.add(InsnGenState.SKIP);
|
||||
}
|
||||
@@ -358,7 +353,7 @@ public class InsnGen {
|
||||
}
|
||||
code.startLine("default: goto " + MethodGen.getLabelName(sw.getDefaultCaseOffset()) + ";");
|
||||
code.decIndent();
|
||||
code.startLine("}");
|
||||
code.startLine('}');
|
||||
state.add(InsnGenState.NO_SEMICOLON);
|
||||
break;
|
||||
|
||||
@@ -376,13 +371,13 @@ public class InsnGen {
|
||||
private void filledNewArray(InsnNode insn, CodeWriter code) throws CodegenException {
|
||||
int c = insn.getArgsCount();
|
||||
code.add("new ").add(useType(insn.getResult().getType()));
|
||||
code.add("{");
|
||||
code.add('{');
|
||||
for (int i = 0; i < c; i++) {
|
||||
code.add(arg(insn, i));
|
||||
if (i + 1 < c)
|
||||
code.add(", ");
|
||||
}
|
||||
code.add("}");
|
||||
code.add('}');
|
||||
}
|
||||
|
||||
private void fillArray(FillArrayOp insn, CodeWriter code) throws CodegenException {
|
||||
|
||||
@@ -133,7 +133,7 @@ public class MethodGen {
|
||||
} else {
|
||||
argsCode.add(TypeGen.translate(classGen, arg.getType()));
|
||||
}
|
||||
argsCode.add(" ");
|
||||
argsCode.add(' ');
|
||||
argsCode.add(makeArgName(arg));
|
||||
|
||||
i++;
|
||||
@@ -253,7 +253,7 @@ public class MethodGen {
|
||||
makeFallbackMethod(code, mth);
|
||||
|
||||
code.decIndent();
|
||||
code.startLine("}");
|
||||
code.startLine('}');
|
||||
code.startLine("*/");
|
||||
}
|
||||
|
||||
|
||||
@@ -254,7 +254,7 @@ public class RegionGen extends InsnGen {
|
||||
code.startLine("} catch (");
|
||||
code.add(handler.isCatchAll() ? "Throwable" : useClass(handler.getCatchType()));
|
||||
code.add(' ');
|
||||
code.add(arg(handler.getArg()));
|
||||
code.add(mgen.assignArg(handler.getArg()));
|
||||
code.add(") {");
|
||||
makeRegionIndent(code, region);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ public class TypeGen {
|
||||
return stype.getLongName();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static String shortString(ArgType type) {
|
||||
final PrimitiveType stype = type.getPrimitiveType();
|
||||
if (stype == null)
|
||||
|
||||
@@ -16,7 +16,7 @@ public class FieldInfo {
|
||||
return new FieldInfo(dex, index);
|
||||
}
|
||||
|
||||
protected FieldInfo(DexNode dex, int ind) {
|
||||
private FieldInfo(DexNode dex, int ind) {
|
||||
FieldId field = dex.getFieldId(ind);
|
||||
this.name = dex.getString(field.getNameIndex());
|
||||
this.type = dex.getType(field.getTypeIndex());
|
||||
|
||||
@@ -5,7 +5,7 @@ import jadx.utils.InsnUtils;
|
||||
|
||||
public class IndexInsnNode extends InsnNode {
|
||||
|
||||
protected final Object index;
|
||||
private final Object index;
|
||||
|
||||
public IndexInsnNode(InsnType type, Object index, int argCount) {
|
||||
super(type, argCount);
|
||||
|
||||
@@ -587,10 +587,7 @@ public abstract class ArgType {
|
||||
return false;
|
||||
}
|
||||
// TODO: don't use toString
|
||||
if (!toString().equals(obj.toString())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return toString().equals(obj.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -72,4 +72,8 @@ public abstract class InsnArg extends Typed {
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getRegNum() {
|
||||
throw new UnsupportedOperationException("Must be called from RegisterArg");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ public class RegisterArg extends InsnArg {
|
||||
this.regNum = rn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRegNum() {
|
||||
return regNum;
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ public class TypedVar {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return type.hashCode() * 31 + ((name == null) ? 0 : name.hashCode());
|
||||
return type.hashCode() * 31 + (name == null ? 0 : name.hashCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -66,12 +66,12 @@ public class TypedVar {
|
||||
if (obj == null) return false;
|
||||
if (getClass() != obj.getClass()) return false;
|
||||
TypedVar other = (TypedVar) obj;
|
||||
if (!type.equals(other.type)) return false;
|
||||
if (name == null) {
|
||||
if (other.name != null) return false;
|
||||
} else if (!name.equals(other.name)) return false;
|
||||
if (type == null) {
|
||||
if (other.type != null) return false;
|
||||
} else if (!type.equals(other.type)) return false;
|
||||
} else if (!name.equals(other.name)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ public class DexNode {
|
||||
private final List<ClassNode> classes = new ArrayList<ClassNode>();
|
||||
private final String[] strings;
|
||||
|
||||
public DexNode(RootNode root, InputFile input) throws IOException, DecodeException {
|
||||
public DexNode(RootNode root, InputFile input) {
|
||||
this.root = root;
|
||||
this.dexBuf = input.getDexBuffer();
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ public class InsnNode extends AttrNode {
|
||||
|
||||
public boolean containsArg(RegisterArg arg) {
|
||||
for (InsnArg a : arguments) {
|
||||
if (a == arg || (a.isRegister() && ((RegisterArg) a).getRegNum() == arg.getRegNum()))
|
||||
if (a == arg || (a.isRegister() && a.getRegNum() == arg.getRegNum()))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -100,8 +100,7 @@ public class MethodNode extends AttrNode implements ILoadable {
|
||||
initJumps(insnByOffset);
|
||||
|
||||
if (mthCode.getDebugInfoOffset() > 0) {
|
||||
DebugInfoParser debugInfo = new DebugInfoParser(this, mthCode.getDebugInfoOffset());
|
||||
debugInfo.process(insnByOffset);
|
||||
(new DebugInfoParser(this, mthCode.getDebugInfoOffset(), insnByOffset)).process();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new DecodeException(this, "Load method exception", e);
|
||||
|
||||
@@ -30,6 +30,7 @@ public class BlockMakerVisitor extends AbstractVisitor {
|
||||
|
||||
// leave these instructions alone in block node
|
||||
private static final Set<InsnType> separateInsns = EnumSet.of(
|
||||
InsnType.RETURN,
|
||||
InsnType.IF,
|
||||
InsnType.SWITCH,
|
||||
InsnType.MONITOR_ENTER,
|
||||
@@ -165,12 +166,8 @@ public class BlockMakerVisitor extends AbstractVisitor {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
computeDominators(mth);
|
||||
|
||||
for (BlockNode block : mth.getBasicBlocks()) {
|
||||
markReturnBlocks(mth, block);
|
||||
}
|
||||
markReturnBlocks(mth);
|
||||
|
||||
int i = 0;
|
||||
while (modifyBlocksTree(mth)) {
|
||||
@@ -178,6 +175,7 @@ public class BlockMakerVisitor extends AbstractVisitor {
|
||||
cleanDomTree(mth);
|
||||
// recalculate dominators tree
|
||||
computeDominators(mth);
|
||||
markReturnBlocks(mth);
|
||||
|
||||
i++;
|
||||
if (i > 100)
|
||||
@@ -273,7 +271,7 @@ public class BlockMakerVisitor extends AbstractVisitor {
|
||||
BlockNode idom = mth.getBasicBlocks().get(id);
|
||||
block.setIDom(idom);
|
||||
idom.getDominatesOn().add(block);
|
||||
} else if (block != entryBlock) {
|
||||
} else {
|
||||
throw new JadxRuntimeException("Can't find immediate dominator for block " + block
|
||||
+ " in " + bs + " prec:" + block.getPredecessors());
|
||||
}
|
||||
@@ -284,9 +282,8 @@ public class BlockMakerVisitor extends AbstractVisitor {
|
||||
private static void markLoops(MethodNode mth) {
|
||||
for (BlockNode block : mth.getBasicBlocks()) {
|
||||
for (BlockNode succ : block.getSuccessors()) {
|
||||
// Every successor that dominates its predecessor
|
||||
// must be the header of a loop.
|
||||
// That is, block -> succ is a back edge.
|
||||
// Every successor that dominates its predecessor is a header of a loop,
|
||||
// block -> succ is a back edge.
|
||||
if (block.getDoms().get(succ.getId())) {
|
||||
succ.getAttributes().add(AttributeFlag.LOOP_START);
|
||||
block.getAttributes().add(AttributeFlag.LOOP_END);
|
||||
@@ -299,10 +296,12 @@ public class BlockMakerVisitor extends AbstractVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
private static void markReturnBlocks(MethodNode mth, BlockNode block) {
|
||||
if (block.getInstructions().size() == 1) {
|
||||
if (block.getInstructions().get(0).getType() == InsnType.RETURN)
|
||||
block.getAttributes().add(AttributeFlag.RETURN);
|
||||
private static void markReturnBlocks(MethodNode mth) {
|
||||
for (BlockNode block : mth.getBasicBlocks()) {
|
||||
if (block.getInstructions().size() == 1) {
|
||||
if (block.getInstructions().get(0).getType() == InsnType.RETURN)
|
||||
block.getAttributes().add(AttributeFlag.RETURN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,9 +45,10 @@ public class BlockProcessingHelper {
|
||||
// set correct type for 'move-exception' operation
|
||||
RegisterArg excArg = me.getResult();
|
||||
if (excHandler.isCatchAll())
|
||||
excArg.getTypedVar().merge(ArgType.THROWABLE);
|
||||
excArg.getTypedVar().forceSetType(ArgType.THROWABLE);
|
||||
else
|
||||
excArg.getTypedVar().merge(excHandler.getCatchType().getType());
|
||||
excArg.getTypedVar().forceSetType(excHandler.getCatchType().getType());
|
||||
// excArg.getTypedVar().merge(excHandler.getCatchType().getType());
|
||||
|
||||
excHandler.setArg(excArg);
|
||||
block.getAttributes().add(handlerAttr);
|
||||
|
||||
@@ -34,7 +34,7 @@ public class ConstInlinerVisitor extends AbstractVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean checkInsn(MethodNode mth, BlockNode block, InsnNode insn) {
|
||||
private static boolean checkInsn(MethodNode mth, BlockNode block, InsnNode insn) {
|
||||
if (insn.getType() == InsnType.CONST) {
|
||||
if (insn.getArgsCount() == 1
|
||||
&& insn.getArg(0).isLiteral()
|
||||
|
||||
@@ -75,7 +75,7 @@ public class DotGraphVisitor extends AbstractVisitor {
|
||||
|
||||
dot.add(conn);
|
||||
|
||||
dot.startLine("}");
|
||||
dot.startLine('}');
|
||||
dot.startLine();
|
||||
|
||||
String fileName = Utils.escape(mth.getMethodInfo().getShortId())
|
||||
@@ -99,7 +99,7 @@ public class DotGraphVisitor extends AbstractVisitor {
|
||||
processRegion(mth, c, dot, conn);
|
||||
}
|
||||
|
||||
dot.startLine("}");
|
||||
dot.startLine('}');
|
||||
} else if (region instanceof BlockNode) {
|
||||
processBlock(mth, (BlockNode) region, dot, conn);
|
||||
}
|
||||
|
||||
@@ -40,8 +40,7 @@ public class MethodInlinerVisitor extends AbstractVisitor {
|
||||
if (block.getInstructions().size() == 1) {
|
||||
InsnNode insn = block.getInstructions().get(0);
|
||||
addInlineAttr(mth, insn);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ public class BlockUtils {
|
||||
return list.get(1);
|
||||
}
|
||||
|
||||
public static List<BlockNode> cleanBlockList(List<BlockNode> list) {
|
||||
private static List<BlockNode> cleanBlockList(List<BlockNode> list) {
|
||||
List<BlockNode> ret = new ArrayList<BlockNode>(list.size());
|
||||
for (BlockNode block : list) {
|
||||
if (!block.getAttributes().contains(AttributeType.EXC_HANDLER))
|
||||
@@ -52,11 +52,8 @@ public class BlockUtils {
|
||||
if (from.getCleanSuccessors().contains(to))
|
||||
return false; // already checked
|
||||
|
||||
if (!from.getSuccessors().contains(to))
|
||||
return false; // not even successor
|
||||
|
||||
return true;
|
||||
}
|
||||
return from.getSuccessors().contains(to);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove exception handlers from block nodes bitset
|
||||
|
||||
@@ -22,7 +22,7 @@ public class StringUtils {
|
||||
return '\'' + res.toString() + '\'';
|
||||
}
|
||||
|
||||
public static void processChar(int c, StringBuilder res) {
|
||||
private static void processChar(int c, StringBuilder res) {
|
||||
switch (c) {
|
||||
case '\n':
|
||||
res.append("\\n");
|
||||
|
||||
@@ -126,7 +126,7 @@ public class Utils {
|
||||
public static String getJadxVersion() {
|
||||
try {
|
||||
Enumeration<URL> resources =
|
||||
new Utils().getClass().getClassLoader().getResources("META-INF/MANIFEST.MF");
|
||||
Utils.class.getClassLoader().getResources("META-INF/MANIFEST.MF");
|
||||
while (resources.hasMoreElements()) {
|
||||
Manifest manifest = new Manifest(resources.nextElement().openStream());
|
||||
String ver = manifest.getMainAttributes().getValue("jadx-version");
|
||||
|
||||
Reference in New Issue
Block a user