ABCExplorer - show inline methods

This commit is contained in:
Jindra Petřík
2023-10-01 18:21:38 +02:00
parent 401ba59e41
commit 2a93e6b133
3 changed files with 67 additions and 8 deletions
@@ -2445,6 +2445,19 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
}
}
public void gotoScriptMethod(SWF swf, String scriptName, int methodIndex) {
abcPanel.decompiledTextArea.addScriptListener(new Runnable() {
@Override
public void run() {
if (abcPanel != null) {
abcPanel.decompiledTextArea.removeScriptListener(this);
abcPanel.decompiledTextArea.gotoMethod(methodIndex);
}
}
});
gotoScriptName(swf, scriptName);
}
public void gotoScriptTrait(SWF swf, String scriptName, int classIndex, int traitIndex) {
abcPanel.decompiledTextArea.addScriptListener(new Runnable() {
@Override
@@ -68,9 +68,14 @@ import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Queue;
import java.util.Set;
import java.util.Stack;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
@@ -549,13 +554,27 @@ public class ABCExplorerDialog extends AppDialog {
if (methodInfo == searchMethodInfo) {
found = true;
} else if (round == 2) {
MethodBody body = abc.findBody(methodInfo);
if (body != null) {
for (AVM2Instruction ins : body.getCode().code) {
if (ins.definition instanceof NewFunctionIns) {
if (ins.operands[0] == methodInfo) {
found = true;
break;
Queue<Integer> methods = new ArrayDeque<>();
Set<Integer> visitedMethods = new HashSet<>();
methods.add(methodInfo);
loopm:
while (!methods.isEmpty()) {
methodInfo = methods.poll();
if (visitedMethods.contains(methodInfo)) {
continue;
}
visitedMethods.add(methodInfo);
MethodBody body = abc.findBody(methodInfo);
if (body != null) {
for (AVM2Instruction ins : body.getCode().code) {
if (ins.definition instanceof NewFunctionIns) {
if (ins.operands[0] == searchMethodInfo) {
found = true;
break loopm;
} else {
methods.add(ins.operands[0]);
}
}
}
}
@@ -564,7 +583,8 @@ public class ABCExplorerDialog extends AppDialog {
if (found) {
DottedChain scriptNameDc = abc.script_info.get(scriptIndex).getSimplePackName(abc);
String scriptName = (scriptNameDc == null ? "script_" + scriptIndex : scriptNameDc.toPrintableString(true));
mainPanel.gotoScriptTrait(abc.getSwf(), scriptName, classIndex, globalTraitIndex);
//mainPanel.gotoScriptTrait(abc.getSwf(), scriptName, classIndex, globalTraitIndex);
mainPanel.gotoScriptMethod(abc.getSwf(), scriptName, searchMethodInfo);
}
return found;
}
@@ -771,6 +771,32 @@ public class DecompiledEditorPane extends DebuggableEditorPane implements CaretL
}
}
public void gotoMethod(int methodId) {
Highlighting tm = Highlighting.searchIndex(highlightedText.getMethodHighlights(), methodId);
if (tm != null) {
int pos = 0;
if (tm.len > 1) {
ignoreCarret = true;
int startPos = tm.startPos + tm.len - 1;
if (startPos <= getDocument().getLength()) {
setCaretPosition(startPos);
}
ignoreCarret = false;
}
pos = tm.startPos;
final int fpos = pos;
new Timer().schedule(new TimerTask() {
@Override
public void run() {
if (fpos <= getDocument().getLength()) {
setCaretPosition(fpos);
}
}
}, 100);
}
}
public void gotoTrait(int traitId) {
boolean isScriptInit = traitId == GraphTextWriter.TRAIT_SCRIPT_INITIALIZER;