diff --git a/jadx-core/src/main/java/jadx/api/JadxDecompiler.java b/jadx-core/src/main/java/jadx/api/JadxDecompiler.java index a0a66cd5b..c70448fe2 100644 --- a/jadx-core/src/main/java/jadx/api/JadxDecompiler.java +++ b/jadx-core/src/main/java/jadx/api/JadxDecompiler.java @@ -37,8 +37,6 @@ import jadx.api.plugins.input.data.ILoadResult; import jadx.api.plugins.options.JadxPluginOptions; import jadx.core.Jadx; import jadx.core.dex.attributes.AFlag; -import jadx.core.dex.attributes.AType; -import jadx.core.dex.attributes.nodes.InlinedAttr; import jadx.core.dex.nodes.ClassNode; import jadx.core.dex.nodes.FieldNode; import jadx.core.dex.nodes.MethodNode; @@ -496,25 +494,11 @@ public final class JadxDecompiler implements Closeable { @ApiStatus.Internal JavaMethod convertMethodNode(MethodNode method) { return methodsMap.computeIfAbsent(method, mthNode -> { - ClassNode codeCls = getCodeParentClass(mthNode.getParentClass()); - return new JavaMethod(convertClassNode(codeCls), mthNode); + ClassNode parentCls = mthNode.getParentClass(); + return new JavaMethod(convertClassNode(parentCls), mthNode); }); } - private static ClassNode getCodeParentClass(ClassNode cls) { - ClassNode codeCls; - InlinedAttr inlinedAttr = cls.get(AType.INLINED); - if (inlinedAttr != null) { - codeCls = inlinedAttr.getInlineCls().getTopParentClass(); - } else { - codeCls = cls.getTopParentClass(); - } - if (codeCls == cls) { - return codeCls; - } - return getCodeParentClass(codeCls); - } - @Nullable public JavaClass searchJavaClassByOrigFullName(String fullName) { return getRoot().getClasses().stream() diff --git a/jadx-core/src/main/java/jadx/api/JavaClass.java b/jadx-core/src/main/java/jadx/api/JavaClass.java index 3d2c40d2e..3c0baa4c9 100644 --- a/jadx-core/src/main/java/jadx/api/JavaClass.java +++ b/jadx-core/src/main/java/jadx/api/JavaClass.java @@ -18,6 +18,7 @@ import jadx.api.metadata.ICodeNodeRef; import jadx.core.dex.attributes.AFlag; import jadx.core.dex.attributes.AType; import jadx.core.dex.attributes.nodes.AnonymousClassAttr; +import jadx.core.dex.attributes.nodes.InlinedAttr; import jadx.core.dex.info.AccessInfo; import jadx.core.dex.nodes.ClassNode; import jadx.core.dex.nodes.FieldNode; @@ -242,19 +243,37 @@ public final class JavaClass implements JavaNode { return parent; } - @Override - public JavaClass getTopParentClass() { - if (cls.contains(AType.ANONYMOUS_CLASS)) { - // moved to usage class - return getParentForAnonymousClass(); - } - return parent == null ? this : parent.getTopParentClass(); + public JavaClass getOriginalTopParentClass() { + return parent == null ? this : parent.getOriginalTopParentClass(); } - private JavaClass getParentForAnonymousClass() { - AnonymousClassAttr attr = cls.get(AType.ANONYMOUS_CLASS); - ClassNode topParentClass = attr.getOuterCls().getTopParentClass(); - return getRootDecompiler().convertClassNode(topParentClass); + /** + * Return top parent class which contains code of this class. + * Code parent can be different from original parent after move or inline + * + * @return this if already a top class + */ + @Override + public JavaClass getTopParentClass() { + JavaClass codeParent = getCodeParent(); + return codeParent == null ? this : codeParent.getTopParentClass(); + } + + /** + * Return parent class which contains code of this class. + * Code parent can be different for original parent after move or inline + */ + public @Nullable JavaClass getCodeParent() { + AnonymousClassAttr anonymousClsAttr = cls.get(AType.ANONYMOUS_CLASS); + if (anonymousClsAttr != null) { + // moved to usage class + return getRootDecompiler().convertClassNode(anonymousClsAttr.getOuterCls()); + } + InlinedAttr inlinedAttr = cls.get(AType.INLINED); + if (inlinedAttr != null) { + return getRootDecompiler().convertClassNode(inlinedAttr.getInlineCls()); + } + return parent; } public AccessInfo getAccessInfo() {