未验证 提交 570e7528 编写于 作者: S Skylot

fix(gui): use correct definition position on jump after code reload (#1273)

上级 91858596
...@@ -419,7 +419,11 @@ public final class JadxDecompiler implements Closeable { ...@@ -419,7 +419,11 @@ public final class JadxDecompiler implements Closeable {
* Get JavaClass by ClassNode without loading and decompilation * Get JavaClass by ClassNode without loading and decompilation
*/ */
JavaClass convertClassNode(ClassNode cls) { JavaClass convertClassNode(ClassNode cls) {
return classesMap.computeIfAbsent(cls, node -> { return classesMap.compute(cls, (node, prevJavaCls) -> {
if (prevJavaCls != null && prevJavaCls.getClassNode() == cls) {
// keep previous variable
return prevJavaCls;
}
if (cls.isInner()) { if (cls.isInner()) {
return new JavaClass(cls, convertClassNode(cls.getParentClass())); return new JavaClass(cls, convertClassNode(cls.getParentClass()));
} }
...@@ -431,7 +435,7 @@ public final class JadxDecompiler implements Closeable { ...@@ -431,7 +435,7 @@ public final class JadxDecompiler implements Closeable {
@ApiStatus.Internal @ApiStatus.Internal
public JavaClass getJavaClassByNode(ClassNode cls) { public JavaClass getJavaClassByNode(ClassNode cls) {
JavaClass javaClass = classesMap.get(cls); JavaClass javaClass = classesMap.get(cls);
if (javaClass != null) { if (javaClass != null && javaClass.getClassNode() == cls) {
return javaClass; return javaClass;
} }
// load parent class if inner // load parent class if inner
...@@ -461,7 +465,7 @@ public final class JadxDecompiler implements Closeable { ...@@ -461,7 +465,7 @@ public final class JadxDecompiler implements Closeable {
@Nullable @Nullable
private JavaMethod getJavaMethodByNode(MethodNode mth) { private JavaMethod getJavaMethodByNode(MethodNode mth) {
JavaMethod javaMethod = methodsMap.get(mth); JavaMethod javaMethod = methodsMap.get(mth);
if (javaMethod != null) { if (javaMethod != null && javaMethod.getMethodNode() == mth) {
return javaMethod; return javaMethod;
} }
if (mth.contains(AFlag.DONT_GENERATE)) { if (mth.contains(AFlag.DONT_GENERATE)) {
...@@ -486,7 +490,7 @@ public final class JadxDecompiler implements Closeable { ...@@ -486,7 +490,7 @@ public final class JadxDecompiler implements Closeable {
@Nullable @Nullable
private JavaField getJavaFieldByNode(FieldNode fld) { private JavaField getJavaFieldByNode(FieldNode fld) {
JavaField javaField = fieldsMap.get(fld); JavaField javaField = fieldsMap.get(fld);
if (javaField != null) { if (javaField != null && javaField.getFieldNode() == fld) {
return javaField; return javaField;
} }
// parent class not loaded yet // parent class not loaded yet
......
...@@ -17,6 +17,7 @@ import jadx.core.dex.info.AccessInfo; ...@@ -17,6 +17,7 @@ import jadx.core.dex.info.AccessInfo;
import jadx.gui.ui.TabbedPane; import jadx.gui.ui.TabbedPane;
import jadx.gui.ui.codearea.ClassCodeContentPanel; import jadx.gui.ui.codearea.ClassCodeContentPanel;
import jadx.gui.ui.panel.ContentPanel; import jadx.gui.ui.panel.ContentPanel;
import jadx.gui.utils.CacheObject;
import jadx.gui.utils.NLS; import jadx.gui.utils.NLS;
import jadx.gui.utils.UiUtils; import jadx.gui.utils.UiUtils;
...@@ -71,13 +72,18 @@ public class JClass extends JLoadableNode implements Comparable<JClass> { ...@@ -71,13 +72,18 @@ public class JClass extends JLoadableNode implements Comparable<JClass> {
update(); update();
} }
public synchronized void reload() { public synchronized void reload(CacheObject cache) {
cache.getNodeCache().removeWholeClass(cls);
cache.getIndexService().remove(cls);
cls.reload(); cls.reload();
loaded = true; loaded = true;
update(); update();
cache.getIndexService().indexCls(cls);
} }
public synchronized void unload() { public synchronized void unload(CacheObject cache) {
cache.getNodeCache().removeWholeClass(cls);
cache.getIndexService().remove(cls);
cls.unload(); cls.unload();
loaded = false; loaded = false;
} }
......
...@@ -254,8 +254,7 @@ public class MainWindow extends JFrame { ...@@ -254,8 +254,7 @@ public class MainWindow extends JFrame {
NLS.str("error_dialog.title"), JOptionPane.ERROR_MESSAGE); NLS.str("error_dialog.title"), JOptionPane.ERROR_MESSAGE);
return; return;
} }
JNode node = cacheObject.getNodeCache().makeFrom(javaNode); tabbedPane.codeJump(cacheObject.getNodeCache().makeFrom(javaNode));
tabbedPane.codeJump(new JumpPosition(node.getRootClass(), node.getLine(), JumpPosition.getDefPos(node)));
} }
} }
......
...@@ -218,8 +218,11 @@ public class TabbedPane extends JTabbedPane { ...@@ -218,8 +218,11 @@ public class TabbedPane extends JTabbedPane {
} }
} }
/**
* Jump to node definition
*/
public void codeJump(JNode node) { public void codeJump(JNode node) {
codeJump(new JumpPosition(node)); codeJump(new JumpPosition(Objects.requireNonNull(node)));
} }
public void codeJump(JumpPosition pos) { public void codeJump(JumpPosition pos) {
......
...@@ -171,7 +171,7 @@ public final class CodeArea extends AbstractCodeArea { ...@@ -171,7 +171,7 @@ public final class CodeArea extends AbstractCodeArea {
return null; return null;
} }
JNode jNode = convertJavaNode(foundNode); JNode jNode = convertJavaNode(foundNode);
return new JumpPosition(jNode.getRootClass(), pos.getLine(), JumpPosition.getDefPos(jNode)); return new JumpPosition(jNode.getRootClass(), pos);
} }
private JNode convertJavaNode(JavaNode javaNode) { private JNode convertJavaNode(JavaNode javaNode) {
...@@ -252,8 +252,7 @@ public final class CodeArea extends AbstractCodeArea { ...@@ -252,8 +252,7 @@ public final class CodeArea extends AbstractCodeArea {
CaretPositionFix caretFix = new CaretPositionFix(this); CaretPositionFix caretFix = new CaretPositionFix(this);
caretFix.save(); caretFix.save();
cls.reload(); cls.reload(getMainWindow().getCacheObject());
getMainWindow().getCacheObject().getIndexService().refreshIndex(cls.getCls());
ClassCodeContentPanel codeContentPanel = (ClassCodeContentPanel) this.contentPanel; ClassCodeContentPanel codeContentPanel = (ClassCodeContentPanel) this.contentPanel;
codeContentPanel.getTabbedPane().refresh(cls); codeContentPanel.getTabbedPane().refresh(cls);
......
...@@ -42,7 +42,6 @@ import jadx.core.dex.nodes.RootNode; ...@@ -42,7 +42,6 @@ import jadx.core.dex.nodes.RootNode;
import jadx.core.dex.visitors.rename.RenameVisitor; import jadx.core.dex.visitors.rename.RenameVisitor;
import jadx.core.utils.Utils; import jadx.core.utils.Utils;
import jadx.core.utils.exceptions.JadxRuntimeException; import jadx.core.utils.exceptions.JadxRuntimeException;
import jadx.gui.jobs.IndexService;
import jadx.gui.jobs.TaskStatus; import jadx.gui.jobs.TaskStatus;
import jadx.gui.settings.JadxProject; import jadx.gui.settings.JadxProject;
import jadx.gui.treemodel.JClass; import jadx.gui.treemodel.JClass;
...@@ -222,14 +221,12 @@ public class RenameDialog extends JDialog { ...@@ -222,14 +221,12 @@ public class RenameDialog extends JDialog {
} }
private void refreshClasses(Set<JClass> updatedTopClasses) { private void refreshClasses(Set<JClass> updatedTopClasses) {
IndexService indexService = cache.getIndexService();
if (updatedTopClasses.size() < 10) { if (updatedTopClasses.size() < 10) {
// small batch => reload // small batch => reload
LOG.debug("Classes to reload: {}", updatedTopClasses.size()); LOG.debug("Classes to reload: {}", updatedTopClasses.size());
for (JClass cls : updatedTopClasses) { for (JClass cls : updatedTopClasses) {
try { try {
cls.reload(); cls.reload(cache);
indexService.refreshIndex(cls.getCls());
} catch (Exception e) { } catch (Exception e) {
LOG.error("Failed to reload class: {}", cls.getFullName(), e); LOG.error("Failed to reload class: {}", cls.getFullName(), e);
} }
...@@ -237,11 +234,10 @@ public class RenameDialog extends JDialog { ...@@ -237,11 +234,10 @@ public class RenameDialog extends JDialog {
} else { } else {
// big batch => unload // big batch => unload
LOG.debug("Classes to unload: {}", updatedTopClasses.size()); LOG.debug("Classes to unload: {}", updatedTopClasses.size());
indexService.setComplete(false); cache.getIndexService().setComplete(false);
for (JClass cls : updatedTopClasses) { for (JClass cls : updatedTopClasses) {
try { try {
cls.unload(); cls.unload(cache);
indexService.remove(cls.getCls());
} catch (Exception e) { } catch (Exception e) {
LOG.error("Failed to unload class: {}", cls.getFullName(), e); LOG.error("Failed to unload class: {}", cls.getFullName(), e);
} }
......
...@@ -45,7 +45,6 @@ public class UsageDialog extends CommonSearchDialog { ...@@ -45,7 +45,6 @@ public class UsageDialog extends CommonSearchDialog {
@Override @Override
protected void openInit() { protected void openInit() {
usageList = new ArrayList<>();
mainWindow.getBackgroundExecutor().execute(NLS.str("progress.load"), mainWindow.getBackgroundExecutor().execute(NLS.str("progress.load"),
this::collectUsageData, this::collectUsageData,
(status) -> { (status) -> {
...@@ -59,6 +58,7 @@ public class UsageDialog extends CommonSearchDialog { ...@@ -59,6 +58,7 @@ public class UsageDialog extends CommonSearchDialog {
} }
private void collectUsageData() { private void collectUsageData() {
usageList = new ArrayList<>();
node.getJavaNode().getUseIn() node.getJavaNode().getUseIn()
.stream() .stream()
.map(JavaNode::getTopParentClass) .map(JavaNode::getTopParentClass)
......
...@@ -25,7 +25,7 @@ public class JNodeCache { ...@@ -25,7 +25,7 @@ public class JNodeCache {
} }
// don't use 'computeIfAbsent' method here, it this cause 'Recursive update' exception // don't use 'computeIfAbsent' method here, it this cause 'Recursive update' exception
JNode jNode = cache.get(javaNode); JNode jNode = cache.get(javaNode);
if (jNode == null) { if (jNode == null || jNode.getJavaNode() != javaNode) {
jNode = convert(javaNode); jNode = convert(javaNode);
cache.put(javaNode, jNode); cache.put(javaNode, jNode);
} }
...@@ -37,13 +37,23 @@ public class JNodeCache { ...@@ -37,13 +37,23 @@ public class JNodeCache {
return null; return null;
} }
JClass jCls = (JClass) cache.get(javaCls); JClass jCls = (JClass) cache.get(javaCls);
if (jCls == null) { if (jCls == null || jCls.getCls() != javaCls) {
jCls = convert(javaCls); jCls = convert(javaCls);
cache.put(javaCls, jCls); cache.put(javaCls, jCls);
} }
return jCls; return jCls;
} }
public void remove(JavaNode javaNode) {
cache.remove(javaNode);
}
public void removeWholeClass(JavaClass javaCls) {
remove(javaCls);
javaCls.getMethods().forEach(this::remove);
javaCls.getFields().forEach(this::remove);
}
private JClass convert(JavaClass cls) { private JClass convert(JavaClass cls) {
JavaClass parentCls = cls.getDeclaringClass(); JavaClass parentCls = cls.getDeclaringClass();
if (parentCls == cls) { if (parentCls == cls) {
......
...@@ -3,7 +3,6 @@ package jadx.gui.utils; ...@@ -3,7 +3,6 @@ package jadx.gui.utils;
import java.util.Objects; import java.util.Objects;
import jadx.api.CodePosition; import jadx.api.CodePosition;
import jadx.api.JavaNode;
import jadx.gui.treemodel.JNode; import jadx.gui.treemodel.JNode;
public class JumpPosition { public class JumpPosition {
...@@ -41,14 +40,6 @@ public class JumpPosition { ...@@ -41,14 +40,6 @@ public class JumpPosition {
return line; return line;
} }
public static int getDefPos(JNode node) {
JavaNode javaNode = node.getJavaNode();
if (javaNode == null) {
return -1;
}
return javaNode.getDefPos();
}
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj) { if (this == obj) {
...@@ -58,7 +49,7 @@ public class JumpPosition { ...@@ -58,7 +49,7 @@ public class JumpPosition {
return false; return false;
} }
JumpPosition position = (JumpPosition) obj; JumpPosition position = (JumpPosition) obj;
return line == position.line && node.equals(position.node) && pos == position.pos; return line == position.line && pos == position.pos && node.equals(position.node);
} }
@Override @Override
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册