use of jadx.api.ICodeWriter in project jadx by skylot.
the class MethodGen method addFallbackMethodCode.
public void addFallbackMethodCode(ICodeWriter code, FallbackOption fallbackOption) {
if (fallbackOption != FALLBACK_MODE) {
// preserve error before unload
List<JadxError> errors = mth.getAll(AType.JADX_ERROR);
try {
// load original instructions
mth.unload();
mth.load();
for (IDexTreeVisitor visitor : Jadx.getFallbackPassesList()) {
DepthTraversal.visit(visitor, mth);
}
errors.forEach(err -> mth.addAttr(AType.JADX_ERROR, err));
} catch (Exception e) {
LOG.error("Error reload instructions in fallback mode:", e);
code.startLine("// Can't load method instructions: " + e.getMessage());
return;
} finally {
errors.forEach(err -> mth.addAttr(AType.JADX_ERROR, err));
}
}
InsnNode[] insnArr = mth.getInstructions();
if (insnArr == null) {
code.startLine("// Can't load method instructions.");
return;
}
if (fallbackOption == COMMENTED_DUMP && mth.getCommentsLevel() != CommentsLevel.DEBUG) {
long insnCountEstimate = Stream.of(insnArr).filter(Objects::nonNull).filter(insn -> insn.getType() != InsnType.NOP).count();
if (insnCountEstimate > 100) {
code.incIndent();
code.startLine("Method dump skipped, instructions count: " + insnArr.length);
if (code.isMetadataSupported()) {
code.startLine("To view this dump change 'Code comments level' option to 'DEBUG'");
} else {
code.startLine("To view this dump add '--comments-level debug' option");
}
code.decIndent();
return;
}
}
code.incIndent();
if (mth.getThisArg() != null) {
code.startLine(nameGen.useArg(mth.getThisArg())).add(" = this;");
}
addFallbackInsns(code, mth, insnArr, fallbackOption);
code.decIndent();
}
use of jadx.api.ICodeWriter in project jadx by skylot.
the class JsonCodeGen method fillMthCode.
private List<JsonCodeLine> fillMthCode(MethodNode mth, MethodGen mthGen) {
if (mth.isNoCode()) {
return Collections.emptyList();
}
ICodeWriter cw = mth.root().makeCodeWriter();
try {
mthGen.addInstructions(cw);
} catch (Exception e) {
throw new JadxRuntimeException("Method generation error", e);
}
ICodeInfo code = cw.finish();
String codeStr = code.getCodeStr();
if (codeStr.isEmpty()) {
return Collections.emptyList();
}
String[] lines = codeStr.split(ICodeWriter.NL);
Map<Integer, Integer> lineMapping = code.getLineMapping();
Map<CodePosition, Object> annotations = code.getAnnotations();
long mthCodeOffset = mth.getMethodCodeOffset() + 16;
int linesCount = lines.length;
List<JsonCodeLine> codeLines = new ArrayList<>(linesCount);
for (int i = 0; i < linesCount; i++) {
String codeLine = lines[i];
int line = i + 2;
JsonCodeLine jsonCodeLine = new JsonCodeLine();
jsonCodeLine.setCode(codeLine);
jsonCodeLine.setSourceLine(lineMapping.get(line));
Object obj = annotations.get(new CodePosition(line));
if (obj instanceof InsnCodeOffset) {
long offset = ((InsnCodeOffset) obj).getOffset();
jsonCodeLine.setOffset("0x" + Long.toHexString(mthCodeOffset + offset * 2));
}
codeLines.add(jsonCodeLine);
}
return codeLines;
}
use of jadx.api.ICodeWriter in project jadx by skylot.
the class JsonCodeGen method processCls.
private JsonClass processCls(ClassNode cls, @Nullable ClassGen parentCodeGen) {
ClassGen classGen;
if (parentCodeGen == null) {
classGen = new ClassGen(cls, args);
} else {
classGen = new ClassGen(cls, parentCodeGen);
}
ClassInfo classInfo = cls.getClassInfo();
JsonClass jsonCls = new JsonClass();
jsonCls.setPkg(classInfo.getAliasPkg());
jsonCls.setDex(cls.getInputFileName());
jsonCls.setName(classInfo.getFullName());
if (classInfo.hasAlias()) {
jsonCls.setAlias(classInfo.getAliasFullName());
}
jsonCls.setType(getClassTypeStr(cls));
jsonCls.setAccessFlags(cls.getAccessFlags().rawValue());
if (!Objects.equals(cls.getSuperClass(), ArgType.OBJECT)) {
jsonCls.setSuperClass(getTypeAlias(cls.getSuperClass()));
}
if (!cls.getInterfaces().isEmpty()) {
jsonCls.setInterfaces(Utils.collectionMap(cls.getInterfaces(), this::getTypeAlias));
}
ICodeWriter cw = new SimpleCodeWriter();
CodeGenUtils.addErrorsAndComments(cw, cls);
classGen.addClassDeclaration(cw);
jsonCls.setDeclaration(cw.getCodeStr());
addFields(cls, jsonCls, classGen);
addMethods(cls, jsonCls, classGen);
addInnerClasses(cls, jsonCls, classGen);
if (!cls.getClassInfo().isInner()) {
List<String> imports = Utils.collectionMap(classGen.getImports(), ClassInfo::getAliasFullName);
Collections.sort(imports);
jsonCls.setImports(imports);
}
return jsonCls;
}
use of jadx.api.ICodeWriter in project jadx by skylot.
the class ClassGen method makeClass.
public ICodeInfo makeClass() throws CodegenException {
ICodeWriter clsBody = cls.root().makeCodeWriter();
addClassCode(clsBody);
ICodeWriter clsCode = cls.root().makeCodeWriter();
if (!"".equals(cls.getPackage())) {
clsCode.add("package ").add(cls.getPackage()).add(';');
clsCode.newLine();
}
int importsCount = imports.size();
if (importsCount != 0) {
List<ClassInfo> sortedImports = new ArrayList<>(imports);
sortedImports.sort(Comparator.comparing(ClassInfo::getAliasFullName));
sortedImports.forEach(classInfo -> {
clsCode.startLine("import ");
ClassNode classNode = cls.root().resolveClass(classInfo);
if (classNode != null) {
clsCode.attachAnnotation(classNode);
}
clsCode.add(classInfo.getAliasFullName());
clsCode.add(';');
});
clsCode.newLine();
imports.clear();
}
clsCode.add(clsBody);
return clsCode.finish();
}
use of jadx.api.ICodeWriter in project jadx by skylot.
the class DebugUtils method printInsns.
private static void printInsns(MethodNode mth, ICodeWriter cw, String indent, IBlock block) {
for (InsnNode insn : block.getInstructions()) {
try {
MethodGen mg = MethodGen.getFallbackMethodGen(mth);
InsnGen ig = new InsnGen(mg, true);
ICodeWriter code = new SimpleCodeWriter();
ig.makeInsn(insn, code);
String codeStr = code.getCodeStr();
List<String> insnStrings = Stream.of(codeStr.split(ICodeWriter.NL)).filter(StringUtils::notBlank).map(s -> "|> " + s).collect(Collectors.toList());
Iterator<String> it = insnStrings.iterator();
while (true) {
String insnStr = it.next();
if (it.hasNext()) {
cw.startLine(indent).add(insnStr);
} else {
printWithAttributes(cw, indent, insnStr, insn);
break;
}
}
} catch (CodegenException e) {
cw.startLine(indent).add(">!! ").add(insn.toString());
}
}
}
Aggregations