[Go-To] Move caret to requested field.

- Also added enum constant declarations to the token parser.
This commit is contained in:
Cody 2024-09-16 18:22:15 -06:00
parent afeab95f0b
commit e756324245

AI 샘플 코드 생성 중입니다

Loading...
7 changed files with 478 additions and 338 deletions

View File

@ -30,9 +30,7 @@ import the.bytecode.club.bytecodeviewer.util.JTextAreaUtils;
import javax.swing.*; import javax.swing.*;
import javax.swing.text.BadLocationException; import javax.swing.text.BadLocationException;
import java.awt.*; import java.awt.*;
import java.awt.event.InputEvent; import java.awt.event.*;
import java.awt.event.KeyEvent;
import java.awt.event.MouseWheelEvent;
/** /**
* Searching on an RSyntaxTextArea using swing highlighting * Searching on an RSyntaxTextArea using swing highlighting
@ -87,6 +85,24 @@ public class SearchableRSyntaxTextArea extends RSyntaxTextArea
GlobalHotKeys.keyPressed(keyEvent); GlobalHotKeys.keyPressed(keyEvent);
})); }));
setCursor(new Cursor(Cursor.TEXT_CURSOR));
getCaret().setBlinkRate(0);
getCaret().setVisible(true);
addFocusListener(new FocusAdapter()
{
@Override
public void focusGained(FocusEvent e)
{
getCaret().setVisible(true);
}
@Override
public void focusLost(FocusEvent e)
{
getCaret().setVisible(true);
}
});
final Font newFont = getFont().deriveFont((float) BytecodeViewer.viewer.getFontSize()); final Font newFont = getFont().deriveFont((float) BytecodeViewer.viewer.getFontSize());
//set number-bar font //set number-bar font

View File

@ -1,17 +1,20 @@
package the.bytecode.club.bytecodeviewer.gui.components.actions; package the.bytecode.club.bytecodeviewer.gui.components.actions;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.Token;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.BytecodeViewPanel;
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.ClassViewer;
import the.bytecode.club.bytecodeviewer.gui.util.BytecodeViewPanelUpdater;
import the.bytecode.club.bytecodeviewer.resources.ResourceContainer; import the.bytecode.club.bytecodeviewer.resources.ResourceContainer;
import the.bytecode.club.bytecodeviewer.resources.classcontainer.ClassFileContainer; import the.bytecode.club.bytecodeviewer.resources.classcontainer.ClassFileContainer;
import the.bytecode.club.bytecodeviewer.resources.classcontainer.locations.ClassFieldLocation; import the.bytecode.club.bytecodeviewer.resources.classcontainer.locations.ClassFieldLocation;
import the.bytecode.club.bytecodeviewer.resources.classcontainer.parser.TokenUtil;
import javax.swing.*; import javax.swing.*;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.text.Element; import javax.swing.text.Element;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.util.HashMap;
/** /**
* Created by Bl3nd. * Created by Bl3nd.
@ -36,20 +39,14 @@ public class GoToAction extends AbstractAction
container.fieldMembers.values().forEach(fields -> fields.forEach(field -> { container.fieldMembers.values().forEach(fields -> fields.forEach(field -> {
if (field.line == line && field.columnStart - 1 <= column && field.columnEnd >= column) if (field.line == line && field.columnStart - 1 <= column && field.columnEnd >= column)
{ {
Element root = textArea.getDocument().getDefaultRootElement();
// Open the class that is associated with the field's owner. // Open the class that is associated with the field's owner.
if (!field.owner.equals(container.getName())) if (!field.owner.equals(container.getName()))
{ {
ResourceContainer resourceContainer = BytecodeViewer.getFileContainer(container.getParentContainer()); openFieldClass(field, textArea);
if (resourceContainer != null)
{
String s = container.getImport(field.owner);
BytecodeViewer.viewer.workPane.addClassResource(resourceContainer, s + ".class");
}
return; return;
} }
Element root = textArea.getDocument().getDefaultRootElement();
ClassFieldLocation first = fields.get(0); ClassFieldLocation first = fields.get(0);
int startOffset = root.getElement(first.line - 1).getStartOffset() + (first.columnStart - 1); int startOffset = root.getElement(first.line - 1).getStartOffset() + (first.columnStart - 1);
textArea.setCaretPosition(startOffset); textArea.setCaretPosition(startOffset);
@ -100,4 +97,82 @@ public class GoToAction extends AbstractAction
} }
})); }));
} }
private void openFieldClass(ClassFieldLocation field, RSyntaxTextArea textArea)
{
String token = textArea.modelToToken(textArea.getCaretPosition()).getLexeme();
ResourceContainer resourceContainer = BytecodeViewer.getFileContainer(container.getParentContainer());
if (resourceContainer != null)
{
String s = container.getImport(field.owner);
BytecodeViewer.viewer.workPane.addClassResource(resourceContainer, s + ".class");
ClassViewer activeResource = (ClassViewer) BytecodeViewer.viewer.workPane.getActiveResource();
HashMap<String, ClassFileContainer> classFiles = BytecodeViewer.viewer.workPane.classFiles;
Thread thread = new Thread(() -> {
try
{
BytecodeViewer.updateBusyStatus(true);
Thread.sleep(1000);
} catch (InterruptedException e)
{
throw new RuntimeException(e);
} finally
{
BytecodeViewer.updateBusyStatus(false);
}
String s2 = activeResource.resource.workingName + "-" + this.container.getDecompiler();
ClassFileContainer classFileContainer = classFiles.get(s2);
classFileContainer.fieldMembers.forEach((field1, field2) -> {
if (field1.equals(token))
{
field2.forEach(classFieldLocation -> {
if (classFieldLocation.type.equals("declaration"))
{
for (int i = 0; i < 3; i++)
{
BytecodeViewPanel panel = activeResource.getPanel(i);
if (panel.textArea != null)
{
if (panel.decompiler.getDecompilerName().equals(this.container.getDecompiler()))
{
Element root = panel.textArea.getDocument().getDefaultRootElement();
int startOffset = root.getElement(classFieldLocation.line - 1).getStartOffset() + (classFieldLocation.columnStart - 1);
panel.textArea.setCaretPosition(startOffset);
for (CaretListener caretListener : panel.textArea.getCaretListeners())
{
if (caretListener instanceof BytecodeViewPanelUpdater.MarkerCaretListener)
{
BytecodeViewPanelUpdater.MarkerCaretListener markerCaretListener = (BytecodeViewPanelUpdater.MarkerCaretListener) caretListener;
markerCaretListener.caretUpdate(new CaretEvent(panel.textArea)
{
@Override
public int getDot()
{
return panel.textArea.getCaret().getDot();
}
@Override
public int getMark()
{
return 0;
}
});
}
}
panel.textArea.requestFocusInWindow();
break;
}
}
}
}
});
}
});
});
thread.start();
}
}
} }

View File

@ -24,6 +24,7 @@ import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.ClassViewer;
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.FileViewer; import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.FileViewer;
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.ResourceViewer; import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.ResourceViewer;
import the.bytecode.club.bytecodeviewer.resources.ResourceContainer; import the.bytecode.club.bytecodeviewer.resources.ResourceContainer;
import the.bytecode.club.bytecodeviewer.resources.classcontainer.ClassFileContainer;
import the.bytecode.club.bytecodeviewer.translation.TranslatedComponents; import the.bytecode.club.bytecodeviewer.translation.TranslatedComponents;
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings; import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
import the.bytecode.club.bytecodeviewer.translation.components.TranslatedJButton; import the.bytecode.club.bytecodeviewer.translation.components.TranslatedJButton;
@ -33,13 +34,10 @@ import the.bytecode.club.uikit.tabpopup.closer.PopupMenuTabsCloseConfiguration;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
import java.awt.event.MouseEvent; import java.util.HashMap;
import java.awt.event.MouseListener;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import static the.bytecode.club.bytecodeviewer.Constants.BLOCK_TAB_MENU;
/** /**
* This pane contains all the resources, as tabs. * This pane contains all the resources, as tabs.
* *
@ -54,6 +52,7 @@ public class Workspace extends TranslatedVisibleComponent {
public final JPanel buttonPanel; public final JPanel buttonPanel;
public final JButton refreshClass; public final JButton refreshClass;
public final Set<String> openedTabs = new HashSet<>(); public final Set<String> openedTabs = new HashSet<>();
public HashMap<String, ClassFileContainer> classFiles = new HashMap<>();
public Workspace() { public Workspace() {
super("Workspace", TranslatedComponents.WORK_SPACE); super("Workspace", TranslatedComponents.WORK_SPACE);

View File

@ -27,7 +27,6 @@ import the.bytecode.club.bytecodeviewer.decompilers.Decompiler;
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.BytecodeViewPanel; import the.bytecode.club.bytecodeviewer.gui.resourceviewer.BytecodeViewPanel;
import the.bytecode.club.bytecodeviewer.resources.Resource; import the.bytecode.club.bytecodeviewer.resources.Resource;
import the.bytecode.club.bytecodeviewer.resources.ResourceContainer; import the.bytecode.club.bytecodeviewer.resources.ResourceContainer;
import the.bytecode.club.bytecodeviewer.resources.classcontainer.ClassFileContainer;
import the.bytecode.club.bytecodeviewer.util.MethodParser; import the.bytecode.club.bytecodeviewer.util.MethodParser;
import javax.swing.*; import javax.swing.*;
@ -38,7 +37,6 @@ import java.awt.event.ComponentEvent;
import java.awt.event.HierarchyEvent; import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener; import java.awt.event.HierarchyListener;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.List; import java.util.List;
import static the.bytecode.club.bytecodeviewer.util.MethodParser.Method; import static the.bytecode.club.bytecodeviewer.util.MethodParser.Method;
@ -59,7 +57,6 @@ public class ClassViewer extends ResourceViewer
public BytecodeViewPanel bytecodeViewPanel2 = new BytecodeViewPanel(1, this); public BytecodeViewPanel bytecodeViewPanel2 = new BytecodeViewPanel(1, this);
public BytecodeViewPanel bytecodeViewPanel3 = new BytecodeViewPanel(2, this); public BytecodeViewPanel bytecodeViewPanel3 = new BytecodeViewPanel(2, this);
public List<MethodParser> methods = Arrays.asList(new MethodParser(), new MethodParser(), new MethodParser()); public List<MethodParser> methods = Arrays.asList(new MethodParser(), new MethodParser(), new MethodParser());
public HashMap<String, ClassFileContainer> classFiles = new HashMap<>();
public ClassViewer(ResourceContainer container, String name) public ClassViewer(ResourceContainer container, String name)
{ {
@ -121,8 +118,7 @@ public class ClassViewer extends ResourceViewer
try try
{ {
Thread.sleep(100); Thread.sleep(100);
} } catch (InterruptedException e)
catch (InterruptedException e)
{ {
e.printStackTrace(); e.printStackTrace();
} }
@ -183,6 +179,21 @@ public class ClassViewer extends ResourceViewer
return BytecodeViewer.viewer.viewPane3.isPaneEditable(); return BytecodeViewer.viewer.viewPane3.isPaneEditable();
} }
public BytecodeViewPanel getPanel(int index)
{
switch (index)
{
case 0:
return bytecodeViewPanel1;
case 1:
return bytecodeViewPanel2;
case 2:
return bytecodeViewPanel3;
}
return null;
}
public static void selectMethod(RSyntaxTextArea area, int methodLine) public static void selectMethod(RSyntaxTextArea area, int methodLine)
{ {
@ -272,8 +283,7 @@ public class ClassViewer extends ResourceViewer
try try
{ {
area.setCaretPosition(area.getLineStartOffset(line)); area.setCaretPosition(area.getLineStartOffset(line));
} } catch (BadLocationException ignored)
catch (BadLocationException ignored)
{ {
} }
} }
@ -292,8 +302,7 @@ public class ClassViewer extends ResourceViewer
{ {
sp.setResizeWeight(1); sp.setResizeWeight(1);
setDividerLocation(sp, 0); setDividerLocation(sp, 0);
} } else
else
setDividerLocation(sp, 0); setDividerLocation(sp, 0);
if (bytecodeViewPanel3.decompiler != Decompiler.NONE) if (bytecodeViewPanel3.decompiler != Decompiler.NONE)
@ -304,8 +313,7 @@ public class ClassViewer extends ResourceViewer
setDividerLocation(sp2, 0.5); setDividerLocation(sp2, 0.5);
else if (bytecodeViewPanel1.decompiler == Decompiler.NONE) else if (bytecodeViewPanel1.decompiler == Decompiler.NONE)
setDividerLocation(sp2, 0); setDividerLocation(sp2, 0);
} } else
else
{ {
sp.setResizeWeight(1); sp.setResizeWeight(1);
sp2.setResizeWeight(0); sp2.setResizeWeight(0);
@ -335,8 +343,7 @@ public class ClassViewer extends ResourceViewer
} }
}); });
} }
} } else
else
{ {
splitter.addHierarchyListener(new HierarchyListener() splitter.addHierarchyListener(new HierarchyListener()
{ {

View File

@ -72,6 +72,8 @@ public class BytecodeViewPanelUpdater implements Runnable
private final JButton button; private final JButton button;
private final byte[] classBytes; private final byte[] classBytes;
public MarkerCaretListener markerCaretListener;
private MyErrorStripe errorStripe;
public SearchableRSyntaxTextArea updateUpdaterTextArea; public SearchableRSyntaxTextArea updateUpdaterTextArea;
public JComboBox<Integer> methodsList; public JComboBox<Integer> methodsList;
public boolean isPanelEditable; public boolean isPanelEditable;
@ -118,7 +120,7 @@ public class BytecodeViewPanelUpdater implements Runnable
if (!container.hasBeenParsed) if (!container.hasBeenParsed)
{ {
container.parse(); container.parse();
viewer.classFiles.put(viewer.resource.workingName + "-" + decompiler.getDecompilerName(), container); BytecodeViewer.viewer.workPane.classFiles.put(viewer.resource.workingName + "-" + decompiler.getDecompilerName(), container);
container.hasBeenParsed = true; container.hasBeenParsed = true;
} }
@ -399,9 +401,6 @@ public class BytecodeViewPanelUpdater implements Runnable
bytecodeViewPanel.textArea = updateUpdaterTextArea; bytecodeViewPanel.textArea = updateUpdaterTextArea;
bytecodeViewPanel.textArea.setMarkOccurrencesColor(Color.ORANGE); bytecodeViewPanel.textArea.setMarkOccurrencesColor(Color.ORANGE);
bytecodeViewPanel.textArea.setCursor(new Cursor(Cursor.TEXT_CURSOR));
bytecodeViewPanel.textArea.getCaret().setVisible(true);
bytecodeViewPanel.textArea.getCaret().setBlinkRate(0);
bytecodeViewPanel.textArea.setHighlighter(new RSyntaxTextAreaHighlighterEx()); bytecodeViewPanel.textArea.setHighlighter(new RSyntaxTextAreaHighlighterEx());
if (bytecodeViewPanel.decompiler != Decompiler.BYTECODE_DISASSEMBLER) if (bytecodeViewPanel.decompiler != Decompiler.BYTECODE_DISASSEMBLER)
@ -426,26 +425,19 @@ public class BytecodeViewPanelUpdater implements Runnable
String editable = isPanelEditable ? " - " + EDITABLE : ""; String editable = isPanelEditable ? " - " + EDITABLE : "";
bytecodeViewPanel.textArea.getTextAreaSearchPanel().getTitleHeader().setText(decompiler.getDecompilerName() + editable); bytecodeViewPanel.textArea.getTextAreaSearchPanel().getTitleHeader().setText(decompiler.getDecompilerName() + editable);
MyErrorStripe errorStripe = new MyErrorStripe(bytecodeViewPanel.textArea); errorStripe = new MyErrorStripe(bytecodeViewPanel.textArea);
bytecodeViewPanel.add(errorStripe, BorderLayout.LINE_END); bytecodeViewPanel.add(errorStripe, BorderLayout.LINE_END);
bytecodeViewPanel.revalidate(); bytecodeViewPanel.revalidate();
bytecodeViewPanel.repaint(); bytecodeViewPanel.repaint();
String classContainerName = viewer.resource.workingName + "-" + decompiler.getDecompilerName(); String classContainerName = viewer.resource.workingName + "-" + decompiler.getDecompilerName();
ClassFileContainer classFileContainer = viewer.classFiles.get(classContainerName); ClassFileContainer classFileContainer = BytecodeViewer.viewer.workPane.classFiles.get(classContainerName);
bytecodeViewPanel.textArea.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_B, InputEvent.CTRL_DOWN_MASK), "goToAction"); bytecodeViewPanel.textArea.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_B, InputEvent.CTRL_DOWN_MASK), "goToAction");
bytecodeViewPanel.textArea.getActionMap().put("goToAction", new GoToAction(classFileContainer)); bytecodeViewPanel.textArea.getActionMap().put("goToAction", new GoToAction(classFileContainer));
bytecodeViewPanel.textArea.addCaretListener(e -> { markerCaretListener = new MarkerCaretListener(classContainerName);
if (bytecodeViewPanel.textArea.isFocusOwner()) bytecodeViewPanel.textArea.addCaretListener(markerCaretListener);
{
RSyntaxTextAreaHighlighterEx highlighterEx = (RSyntaxTextAreaHighlighterEx) bytecodeViewPanel.textArea.getHighlighter();
highlighterEx.clearMarkOccurrencesHighlights();
RSyntaxTextArea textArea = (RSyntaxTextArea) e.getSource();
markOccurrences(textArea, viewer.classFiles.get(classContainerName), errorStripe);
}
});
} }
private void markOccurrences(RSyntaxTextArea textArea, ClassFileContainer classFileContainer, MyErrorStripe errorStripe) private void markOccurrences(RSyntaxTextArea textArea, ClassFileContainer classFileContainer, MyErrorStripe errorStripe)
@ -627,4 +619,24 @@ public class BytecodeViewPanelUpdater implements Runnable
} }
})); }));
} }
public class MarkerCaretListener implements CaretListener
{
private final String classContainerName;
public MarkerCaretListener(String classContainerName)
{
this.classContainerName = classContainerName;
}
@Override
public void caretUpdate(CaretEvent e)
{
SearchableRSyntaxTextArea textArea = (SearchableRSyntaxTextArea) e.getSource();
RSyntaxTextAreaHighlighterEx highlighterEx = (RSyntaxTextAreaHighlighterEx) bytecodeViewPanel.textArea.getHighlighter();
highlighterEx.clearMarkOccurrencesHighlights();
markOccurrences(textArea, BytecodeViewer.viewer.workPane.classFiles.get(classContainerName), errorStripe);
}
}
} }

View File

@ -57,6 +57,10 @@ public class ClassFileContainer
return this.className.substring(this.className.lastIndexOf('.') + 1); return this.className.substring(this.className.lastIndexOf('.') + 1);
} }
public String getDecompiler() {
return getName().substring(6);
}
public String getParentContainer() public String getParentContainer()
{ {
return this.parentContainer; return this.parentContainer;

View File

@ -1312,6 +1312,12 @@ public class MyVoidVisitor extends VoidVisitorAdapter<Object>
} }
} }
/**
* Visit all {@link LambdaExpr}'s.
*
* @param n The current {@code LambdaExpr}
* @param arg Don't worry about it.
*/
@Override @Override
public void visit(LambdaExpr n, Object arg) public void visit(LambdaExpr n, Object arg)
{ {
@ -1337,6 +1343,27 @@ public class MyVoidVisitor extends VoidVisitorAdapter<Object>
} }
} }
/**
* Visit all {@link EnumDeclaration}'s.
*
* @param n The current {@code EnumDeclaration}
* @param arg Don't worry about it.
*/
@Override
public void visit(EnumDeclaration n, Object arg)
{
super.visit(n, arg);
n.getEntries().forEach(entry -> {
SimpleName simpleName = entry.getName();
String name = simpleName.getIdentifier();
Range range = simpleName.getRange().get();
int line = range.begin.line;
int columnStart = range.begin.column;
int columnEnd = range.end.column;
this.classFileContainer.putField(name, new ClassFieldLocation(getOwner(), "declaration", line, columnStart, columnEnd + 1));
});
}
/** /**
* Look through the {@link CompilationUnit} for the specific statement within its methods. * Look through the {@link CompilationUnit} for the specific statement within its methods.
* *