diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/usage/UsageInfoVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/usage/UsageInfoVisitor.java index a64fb3bd40f53f0d1e0210386396b99841f4a55a..19989c8be4a57c424be6c05b0cdc00929d3101f6 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/usage/UsageInfoVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/usage/UsageInfoVisitor.java @@ -6,6 +6,8 @@ import org.slf4j.LoggerFactory; import jadx.api.plugins.input.data.ICodeReader; import jadx.api.plugins.input.insns.InsnData; import jadx.api.plugins.input.insns.Opcode; +import jadx.core.dex.attributes.AType; +import jadx.core.dex.attributes.nodes.MethodOverrideAttr; import jadx.core.dex.info.FieldInfo; import jadx.core.dex.info.MethodInfo; import jadx.core.dex.instructions.args.ArgType; @@ -15,12 +17,14 @@ import jadx.core.dex.nodes.MethodNode; import jadx.core.dex.nodes.RootNode; import jadx.core.dex.visitors.AbstractVisitor; import jadx.core.dex.visitors.JadxVisitor; +import jadx.core.dex.visitors.OverrideMethodVisitor; import jadx.core.dex.visitors.RenameVisitor; @JadxVisitor( name = "UsageInfoVisitor", desc = "Scan class and methods to collect usage info and class dependencies", runAfter = { + OverrideMethodVisitor.class, // add method override as use RenameVisitor.class // sort by alias name } ) @@ -63,6 +67,12 @@ public class UsageInfoVisitor extends AbstractVisitor { } catch (Exception e) { mth.addError("Dependency scan failed", e); } + MethodOverrideAttr overrideAttr = mth.get(AType.METHOD_OVERRIDE); + if (overrideAttr != null) { + for (MethodNode relatedMthNode : overrideAttr.getRelatedMthNodes()) { + usageInfo.methodUse(relatedMthNode, mth); + } + } } private static void processInstructions(MethodNode mth, UsageInfo usageInfo) { diff --git a/jadx-gui/src/main/java/jadx/gui/treemodel/JClass.java b/jadx-gui/src/main/java/jadx/gui/treemodel/JClass.java index f6131dc7d75a58664f702f470555d2722b638d61..441358a9968bbb5ecf4c76a4ec24aa7375c684df 100644 --- a/jadx-gui/src/main/java/jadx/gui/treemodel/JClass.java +++ b/jadx-gui/src/main/java/jadx/gui/treemodel/JClass.java @@ -10,6 +10,7 @@ import jadx.api.JavaClass; import jadx.api.JavaField; import jadx.api.JavaMethod; import jadx.api.JavaNode; +import jadx.core.dex.attributes.AFlag; import jadx.core.dex.info.AccessInfo; import jadx.gui.utils.NLS; import jadx.gui.utils.UiUtils; @@ -50,6 +51,11 @@ public class JClass extends JLoadableNode { getRootClass().load(); } + @Override + public boolean canRename() { + return !cls.getClassNode().contains(AFlag.DONT_RENAME); + } + public synchronized void load() { if (!loaded) { cls.decompile(); diff --git a/jadx-gui/src/main/java/jadx/gui/treemodel/JField.java b/jadx-gui/src/main/java/jadx/gui/treemodel/JField.java index 8d84fc7ef5d40fb0bde9014dd01fe43b14642430..6f9052d36ea8209f32a6f4dc76da0bb11a2fa54b 100644 --- a/jadx-gui/src/main/java/jadx/gui/treemodel/JField.java +++ b/jadx-gui/src/main/java/jadx/gui/treemodel/JField.java @@ -5,6 +5,7 @@ import javax.swing.ImageIcon; import jadx.api.JavaField; import jadx.api.JavaNode; +import jadx.core.dex.attributes.AFlag; import jadx.core.dex.info.AccessInfo; import jadx.gui.utils.OverlayIcon; import jadx.gui.utils.UiUtils; @@ -43,6 +44,11 @@ public class JField extends JNode { return jParent.getRootClass(); } + @Override + public boolean canRename() { + return !field.getFieldNode().contains(AFlag.DONT_RENAME); + } + @Override public int getLine() { return field.getDecompiledLine(); diff --git a/jadx-gui/src/main/java/jadx/gui/treemodel/JMethod.java b/jadx-gui/src/main/java/jadx/gui/treemodel/JMethod.java index ec185b00fca09a0d00723df9a492679bede7e867..04f724a2611d9b3c8c41032909c1064839ed0a01 100644 --- a/jadx-gui/src/main/java/jadx/gui/treemodel/JMethod.java +++ b/jadx-gui/src/main/java/jadx/gui/treemodel/JMethod.java @@ -7,6 +7,7 @@ import javax.swing.ImageIcon; import jadx.api.JavaMethod; import jadx.api.JavaNode; +import jadx.core.dex.attributes.AFlag; import jadx.core.dex.info.AccessInfo; import jadx.core.dex.instructions.args.ArgType; import jadx.gui.utils.OverlayIcon; @@ -68,6 +69,11 @@ public class JMethod extends JNode { return icon; } + @Override + public boolean canRename() { + return !mth.getMethodNode().contains(AFlag.DONT_RENAME); + } + String makeBaseString() { if (mth.isClassInit()) { return "{...}"; diff --git a/jadx-gui/src/main/java/jadx/gui/treemodel/JNode.java b/jadx-gui/src/main/java/jadx/gui/treemodel/JNode.java index 96b53ee37eb65a1d5bc3261bf739fef38616476c..56f31fa9472c96bf1d438a63f9e5239464933896 100644 --- a/jadx-gui/src/main/java/jadx/gui/treemodel/JNode.java +++ b/jadx-gui/src/main/java/jadx/gui/treemodel/JNode.java @@ -75,6 +75,10 @@ public abstract class JNode extends DefaultMutableTreeNode { return javaNode.getName(); } + public boolean canRename() { + return false; + } + public abstract String makeString(); public String makeStringHtml() { diff --git a/jadx-gui/src/main/java/jadx/gui/treemodel/JPackage.java b/jadx-gui/src/main/java/jadx/gui/treemodel/JPackage.java index ccbd855d5193f32061479ae20a1668f0d415dcfd..e8e6d4c1aa8234bbb61b29dfad9a7b655fafe3ff 100644 --- a/jadx-gui/src/main/java/jadx/gui/treemodel/JPackage.java +++ b/jadx-gui/src/main/java/jadx/gui/treemodel/JPackage.java @@ -74,6 +74,11 @@ public class JPackage extends JNode implements Comparable { return name; } + @Override + public boolean canRename() { + return true; + } + public String getFullName() { return fullName; } diff --git a/jadx-gui/src/main/java/jadx/gui/ui/RenameDialog.java b/jadx-gui/src/main/java/jadx/gui/ui/RenameDialog.java index 9a8c18840388d3ca7fce43620aaff63eda767d06..ac89928f0161b69333e47b51e62dab9ea566ae22 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/RenameDialog.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/RenameDialog.java @@ -26,6 +26,9 @@ import jadx.api.JavaField; import jadx.api.JavaMethod; import jadx.api.JavaNode; import jadx.core.codegen.CodeWriter; +import jadx.core.dex.attributes.AType; +import jadx.core.dex.attributes.nodes.MethodOverrideAttr; +import jadx.core.dex.nodes.MethodNode; import jadx.core.dex.nodes.RootNode; import jadx.core.dex.visitors.RenameVisitor; import jadx.core.utils.Utils; @@ -113,7 +116,13 @@ public class RenameDialog extends JDialog { if (node instanceof JMethod) { JavaMethod javaMethod = (JavaMethod) node.getJavaNode(); type = "m"; - id = javaMethod.getMethodNode().getMethodInfo().getRawFullId(); + MethodNode mthNode = javaMethod.getMethodNode(); + MethodOverrideAttr overrideAttr = mthNode.get(AType.METHOD_OVERRIDE); + if (overrideAttr != null) { + // use method closest to base method + mthNode = Objects.requireNonNull(Utils.last(overrideAttr.getRelatedMthNodes())); + } + id = mthNode.getMethodInfo().getRawFullId(); } else if (node instanceof JField) { JavaField javaField = (JavaField) node.getJavaNode(); type = "f"; diff --git a/jadx-gui/src/main/java/jadx/gui/ui/codearea/CodeLinkGenerator.java b/jadx-gui/src/main/java/jadx/gui/ui/codearea/CodeLinkGenerator.java index 54e7233ddf426037eed656356257768e4cf982b5..939230ef39735c0b29d159a87441c8b4d6ef6e8d 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/codearea/CodeLinkGenerator.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/codearea/CodeLinkGenerator.java @@ -13,6 +13,7 @@ import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import jadx.api.JavaNode; import jadx.gui.treemodel.JNode; import jadx.gui.utils.JumpPosition; @@ -27,6 +28,22 @@ public class CodeLinkGenerator implements LinkGenerator { this.jNode = codeArea.getNode(); } + public JavaNode getNodeAtOffset(RSyntaxTextArea textArea, int offset) { + try { + if (jNode.getCodeInfo() == null) { + return null; + } + int sourceOffset = getLinkSourceOffset(textArea, offset); + if (sourceOffset == -1) { + return null; + } + return codeArea.getJavaNodeAtOffset(offset); + } catch (Exception e) { + LOG.error("getNodeAtOffset error", e); + return null; + } + } + @Nullable public JumpPosition getJumpLinkAtOffset(RSyntaxTextArea textArea, int offset) { try { diff --git a/jadx-gui/src/main/java/jadx/gui/ui/codearea/MouseHoverHighlighter.java b/jadx-gui/src/main/java/jadx/gui/ui/codearea/MouseHoverHighlighter.java index 16833ffae4085ca62c27627bcb7babb14288eecc..225ecbbd8056178b878ecff77ff71e7b565f0b0e 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/codearea/MouseHoverHighlighter.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/codearea/MouseHoverHighlighter.java @@ -11,7 +11,7 @@ import org.fife.ui.rtextarea.SmartHighlightPainter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import jadx.gui.utils.JumpPosition; +import jadx.api.JavaNode; class MouseHoverHighlighter extends MouseMotionAdapter { private static final Logger LOG = LoggerFactory.getLogger(MouseHoverHighlighter.class); @@ -50,8 +50,8 @@ class MouseHoverHighlighter extends MouseMotionAdapter { // don't repaint highlight return true; } - JumpPosition jump = codeLinkGenerator.getJumpLinkAtOffset(codeArea, tokenOffset); - if (jump == null) { + JavaNode nodeAtOffset = codeLinkGenerator.getNodeAtOffset(codeArea, tokenOffset); + if (nodeAtOffset == null) { return false; } removeHighlight(); diff --git a/jadx-gui/src/main/java/jadx/gui/ui/codearea/RenameAction.java b/jadx-gui/src/main/java/jadx/gui/ui/codearea/RenameAction.java index 0bf175b94d41996b3ed8ff6f40ad43f95e078ea3..0ee2798b27dd441a9ecf26c1d2a546e59db82c38 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/codearea/RenameAction.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/codearea/RenameAction.java @@ -2,6 +2,8 @@ package jadx.gui.ui.codearea; import java.awt.event.ActionEvent; +import javax.swing.event.PopupMenuEvent; + import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -19,6 +21,12 @@ public final class RenameAction extends JNodeMenuAction { super(NLS.str("popup.rename"), codeArea); } + @Override + public void popupMenuWillBecomeVisible(PopupMenuEvent e) { + super.popupMenuWillBecomeVisible(e); + setEnabled(node != null && node.canRename()); + } + @Override public void actionPerformed(ActionEvent e) { if (node == null) {