feat: option to disable inner classes move to parent (#1817)
This commit is contained in:
@@ -69,6 +69,7 @@ public class JadxArgs implements Closeable {
|
||||
private boolean inlineAnonymousClasses = true;
|
||||
private boolean inlineMethods = true;
|
||||
private boolean allowInlineKotlinLambda = true;
|
||||
private boolean moveInnerClasses = true;
|
||||
|
||||
private boolean skipResources = false;
|
||||
private boolean skipSources = false;
|
||||
@@ -305,6 +306,14 @@ public class JadxArgs implements Closeable {
|
||||
this.allowInlineKotlinLambda = allowInlineKotlinLambda;
|
||||
}
|
||||
|
||||
public boolean isMoveInnerClasses() {
|
||||
return moveInnerClasses;
|
||||
}
|
||||
|
||||
public void setMoveInnerClasses(boolean moveInnerClasses) {
|
||||
this.moveInnerClasses = moveInnerClasses;
|
||||
}
|
||||
|
||||
public boolean isExtractFinally() {
|
||||
return extractFinally;
|
||||
}
|
||||
@@ -628,7 +637,7 @@ public class JadxArgs implements Closeable {
|
||||
*/
|
||||
public String makeCodeArgsHash() {
|
||||
String argStr = "args:" + decompilationMode + useImports + showInconsistentCode
|
||||
+ inlineAnonymousClasses + inlineMethods
|
||||
+ inlineAnonymousClasses + inlineMethods + moveInnerClasses + allowInlineKotlinLambda
|
||||
+ deobfuscationOn + deobfuscationMinLength + deobfuscationMaxLength
|
||||
+ resourceNameSource
|
||||
+ parseKotlinMetadata + useKotlinMethodsForVarNames
|
||||
|
||||
@@ -22,9 +22,9 @@ public final class ClassInfo implements Comparable<ClassInfo> {
|
||||
@Nullable
|
||||
private ClassAliasInfo alias;
|
||||
|
||||
private ClassInfo(RootNode root, ArgType type, boolean inner) {
|
||||
private ClassInfo(RootNode root, ArgType type) {
|
||||
this.type = type;
|
||||
splitAndApplyNames(root, type, inner);
|
||||
splitAndApplyNames(root, type, root.getArgs().isMoveInnerClasses());
|
||||
}
|
||||
|
||||
public static ClassInfo fromType(RootNode root, ArgType type) {
|
||||
@@ -33,7 +33,7 @@ public final class ClassInfo implements Comparable<ClassInfo> {
|
||||
if (cls != null) {
|
||||
return cls;
|
||||
}
|
||||
ClassInfo newClsInfo = new ClassInfo(root, clsType, true);
|
||||
ClassInfo newClsInfo = new ClassInfo(root, clsType);
|
||||
return root.getInfoStorage().putCls(newClsInfo);
|
||||
}
|
||||
|
||||
@@ -147,16 +147,21 @@ public final class ClassInfo implements Comparable<ClassInfo> {
|
||||
clsName = fullObjectName.substring(dot + 1);
|
||||
}
|
||||
|
||||
int sep = clsName.lastIndexOf('$');
|
||||
if (canBeInner && sep > 0 && sep != clsName.length() - 1) {
|
||||
String parClsName = clsPkg + '.' + clsName.substring(0, sep);
|
||||
if (clsPkg.isEmpty()) {
|
||||
parClsName = clsName.substring(0, sep);
|
||||
boolean innerCls = false;
|
||||
if (canBeInner) {
|
||||
int sep = clsName.lastIndexOf('$');
|
||||
if (sep > 0 && sep != clsName.length() - 1) {
|
||||
String parClsName = clsPkg + '.' + clsName.substring(0, sep);
|
||||
if (clsPkg.isEmpty()) {
|
||||
parClsName = clsName.substring(0, sep);
|
||||
}
|
||||
pkg = null;
|
||||
parentClass = fromName(root, parClsName);
|
||||
clsName = clsName.substring(sep + 1);
|
||||
innerCls = true;
|
||||
}
|
||||
pkg = null;
|
||||
parentClass = fromName(root, parClsName);
|
||||
clsName = clsName.substring(sep + 1);
|
||||
} else {
|
||||
}
|
||||
if (!innerCls) {
|
||||
pkg = clsPkg;
|
||||
parentClass = null;
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ public class ClassNode extends NotificationAttrNode
|
||||
// store smali
|
||||
private String smali;
|
||||
// store parent for inner classes or 'this' otherwise
|
||||
private ClassNode parentClass;
|
||||
private ClassNode parentClass = this;
|
||||
|
||||
private volatile ProcessState state = ProcessState.NOT_LOADED;
|
||||
private LoadStage loadStage = LoadStage.NONE;
|
||||
@@ -225,7 +225,6 @@ public class ClassNode extends NotificationAttrNode
|
||||
this.methods = new ArrayList<>();
|
||||
this.fields = new ArrayList<>();
|
||||
this.accessFlags = new AccessInfo(accessFlags, AFType.CLASS);
|
||||
this.parentClass = this;
|
||||
this.packageNode = PackageNode.getForClass(root, clsInfo.getPackage(), this);
|
||||
}
|
||||
|
||||
@@ -555,6 +554,8 @@ public class ClassNode extends NotificationAttrNode
|
||||
parentClass = parent;
|
||||
return;
|
||||
}
|
||||
// undo inner mark in class info
|
||||
clsInfo.notInner(root);
|
||||
}
|
||||
parentClass = this;
|
||||
}
|
||||
@@ -667,8 +668,7 @@ public class ClassNode extends NotificationAttrNode
|
||||
/**
|
||||
* Get all inner and inlined classes recursively
|
||||
*
|
||||
* @param resultClassesSet
|
||||
* all identified inner and inlined classes are added to this set
|
||||
* @param resultClassesSet all identified inner and inlined classes are added to this set
|
||||
*/
|
||||
public void getInnerAndInlinedClassesRecursive(Set<ClassNode> resultClassesSet) {
|
||||
for (ClassNode innerCls : innerClasses) {
|
||||
|
||||
@@ -142,9 +142,11 @@ public class RootNode {
|
||||
|
||||
// sort classes by name, expect top classes before inner
|
||||
classes.sort(Comparator.comparing(ClassNode::getFullName));
|
||||
// move inner classes
|
||||
initInnerClasses();
|
||||
|
||||
if (args.isMoveInnerClasses()) {
|
||||
// detect and move inner classes
|
||||
initInnerClasses();
|
||||
}
|
||||
// sort packages
|
||||
Collections.sort(packages);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user