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