Add ability to open an accessed fields parent class.
This commit is contained in:
parent
262a408c95
commit
afeab95f0b
|
@ -2,6 +2,9 @@ package the.bytecode.club.bytecodeviewer.gui.components.actions;
|
|||
|
||||
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.resources.ResourceContainer;
|
||||
import the.bytecode.club.bytecodeviewer.resources.classcontainer.ClassFileContainer;
|
||||
import the.bytecode.club.bytecodeviewer.resources.classcontainer.locations.ClassFieldLocation;
|
||||
import the.bytecode.club.bytecodeviewer.resources.classcontainer.parser.TokenUtil;
|
||||
|
@ -31,7 +34,21 @@ public class GoToAction extends AbstractAction
|
|||
int column = textArea.getCaretOffsetFromLineStart();
|
||||
|
||||
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)
|
||||
{
|
||||
// Open the class that is associated with the field's owner.
|
||||
if (!field.owner.equals(container.getName()))
|
||||
{
|
||||
ResourceContainer resourceContainer = BytecodeViewer.getFileContainer(container.getParentContainer());
|
||||
if (resourceContainer != null)
|
||||
{
|
||||
String s = container.getImport(field.owner);
|
||||
BytecodeViewer.viewer.workPane.addClassResource(resourceContainer, s + ".class");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Element root = textArea.getDocument().getDefaultRootElement();
|
||||
ClassFieldLocation first = fields.get(0);
|
||||
int startOffset = root.getElement(first.line - 1).getStartOffset() + (first.columnStart - 1);
|
||||
|
@ -40,15 +57,19 @@ public class GoToAction extends AbstractAction
|
|||
}));
|
||||
|
||||
container.methodParameterMembers.values().forEach(parameters -> parameters.forEach(parameter -> {
|
||||
if (parameter.line == line && parameter.columnStart - 1 <= column && parameter.columnEnd >= column) {
|
||||
if (parameter.line == line && parameter.columnStart - 1 <= column && parameter.columnEnd >= column)
|
||||
{
|
||||
Element root = textArea.getDocument().getDefaultRootElement();
|
||||
if (parameter.decRef.equalsIgnoreCase("declaration")) {
|
||||
if (parameter.decRef.equalsIgnoreCase("declaration"))
|
||||
{
|
||||
int startOffset = root.getElement(parameter.line - 1).getStartOffset() + (parameter.columnStart - 1);
|
||||
textArea.setCaretPosition(startOffset);
|
||||
} else {
|
||||
} else
|
||||
{
|
||||
String method = parameter.method;
|
||||
parameters.stream().filter(classParameterLocation -> classParameterLocation.method.equals(method)).forEach(classParameterLocation -> {
|
||||
if (classParameterLocation.decRef.equalsIgnoreCase("declaration")) {
|
||||
if (classParameterLocation.decRef.equalsIgnoreCase("declaration"))
|
||||
{
|
||||
int startOffset = root.getElement(classParameterLocation.line - 1).getStartOffset() + (classParameterLocation.columnStart - 1);
|
||||
textArea.setCaretPosition(startOffset);
|
||||
}
|
||||
|
@ -58,15 +79,19 @@ public class GoToAction extends AbstractAction
|
|||
}));
|
||||
|
||||
container.methodLocalMembers.values().forEach(localMembers -> localMembers.forEach(localMember -> {
|
||||
if (localMember.line == line && localMember.columnStart - 1 <= column && localMember.columnEnd >= column) {
|
||||
if (localMember.line == line && localMember.columnStart - 1 <= column && localMember.columnEnd >= column)
|
||||
{
|
||||
Element root = textArea.getDocument().getDefaultRootElement();
|
||||
if (localMember.decRef.equals("declaration")) {
|
||||
if (localMember.decRef.equals("declaration"))
|
||||
{
|
||||
int startOffset = root.getElement(localMember.line - 1).getStartOffset() + (localMember.columnStart - 1);
|
||||
textArea.setCaretPosition(startOffset);
|
||||
} else {
|
||||
} else
|
||||
{
|
||||
String method = localMember.method;
|
||||
localMembers.stream().filter(classLocalVariableLocation -> classLocalVariableLocation.method.equals(method)).forEach(classLocalVariableLocation -> {
|
||||
if (classLocalVariableLocation.decRef.equalsIgnoreCase("declaration")) {
|
||||
if (classLocalVariableLocation.decRef.equalsIgnoreCase("declaration"))
|
||||
{
|
||||
int startOffset = root.getElement(classLocalVariableLocation.line - 1).getStartOffset() + (classLocalVariableLocation.columnStart - 1);
|
||||
textArea.setCaretPosition(startOffset);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -26,15 +26,18 @@ public class ClassFileContainer
|
|||
public transient NavigableMap<String, ArrayList<ClassParameterLocation>> methodParameterMembers = new TreeMap<>();
|
||||
public transient NavigableMap<String, ArrayList<ClassLocalVariableLocation>> methodLocalMembers = new TreeMap<>();
|
||||
public transient NavigableMap<String, ArrayList<ClassMethodLocation>> methodMembers = new TreeMap<>();
|
||||
public transient NavigableMap<String, String> imports = new TreeMap<>();
|
||||
|
||||
public boolean hasBeenParsed = false;
|
||||
public final String className;
|
||||
private final String content;
|
||||
private final String parentContainer;
|
||||
|
||||
public ClassFileContainer(String className, String content)
|
||||
public ClassFileContainer(String className, String content, String parentContainer)
|
||||
{
|
||||
this.className = className;
|
||||
this.content = content;
|
||||
this.parentContainer = parentContainer;
|
||||
}
|
||||
|
||||
public void parse()
|
||||
|
@ -50,6 +53,15 @@ public class ClassFileContainer
|
|||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.className.substring(this.className.lastIndexOf('.') + 1);
|
||||
}
|
||||
|
||||
public String getParentContainer()
|
||||
{
|
||||
return this.parentContainer;
|
||||
}
|
||||
|
||||
public void putField(String key, ClassFieldLocation value)
|
||||
{
|
||||
this.fieldMembers.computeIfAbsent(key, v -> new ArrayList<>()).add(value);
|
||||
|
@ -89,4 +101,14 @@ public class ClassFileContainer
|
|||
{
|
||||
return methodMembers.getOrDefault(key, new ArrayList<>());
|
||||
}
|
||||
|
||||
public void putImport(String key, String value)
|
||||
{
|
||||
this.imports.put(key, value);
|
||||
}
|
||||
|
||||
public String getImport(String key) {
|
||||
String value = this.imports.get(key);
|
||||
return value + "/" + key;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,11 @@ package the.bytecode.club.bytecodeviewer.resources.classcontainer.parser;
|
|||
|
||||
import com.github.javaparser.Range;
|
||||
import com.github.javaparser.ast.CompilationUnit;
|
||||
import com.github.javaparser.ast.ImportDeclaration;
|
||||
import com.github.javaparser.ast.body.*;
|
||||
import com.github.javaparser.ast.expr.*;
|
||||
import com.github.javaparser.ast.stmt.*;
|
||||
import com.github.javaparser.ast.type.ClassOrInterfaceType;
|
||||
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
|
||||
import com.github.javaparser.resolution.UnsolvedSymbolException;
|
||||
import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
|
||||
|
@ -14,6 +16,7 @@ import the.bytecode.club.bytecodeviewer.resources.classcontainer.locations.Class
|
|||
import the.bytecode.club.bytecodeviewer.resources.classcontainer.locations.ClassMethodLocation;
|
||||
import the.bytecode.club.bytecodeviewer.resources.classcontainer.locations.ClassParameterLocation;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
|
@ -34,7 +37,7 @@ public class MyVoidVisitor extends VoidVisitorAdapter<Object>
|
|||
|
||||
private String getOwner()
|
||||
{
|
||||
return this.classFileContainer.className.substring(this.classFileContainer.className.lastIndexOf('.') + 1);
|
||||
return this.classFileContainer.getName();
|
||||
}
|
||||
|
||||
private String getMethod(CallableDeclaration<?> method)
|
||||
|
@ -66,6 +69,17 @@ public class MyVoidVisitor extends VoidVisitorAdapter<Object>
|
|||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ImportDeclaration n, Object arg)
|
||||
{
|
||||
super.visit(n, arg);
|
||||
Name class_ = n.getName();
|
||||
String className = class_.getIdentifier();
|
||||
String package_ = Objects.requireNonNull(class_.getQualifier().orElse(null)).asString();
|
||||
package_ = package_.replace('.', '/');
|
||||
this.classFileContainer.putImport(className, package_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visit all {@link FieldAccessExpr}s.
|
||||
* <p>
|
||||
|
@ -85,7 +99,6 @@ public class MyVoidVisitor extends VoidVisitorAdapter<Object>
|
|||
int line = range.begin.line;
|
||||
int columnStart = range.begin.column;
|
||||
int columnEnd = range.end.column;
|
||||
this.classFileContainer.putField(fieldName, new ClassFieldLocation(getOwner(), "reference", line, columnStart, columnEnd + 1));
|
||||
|
||||
if (n.hasScope())
|
||||
{
|
||||
|
@ -101,15 +114,15 @@ public class MyVoidVisitor extends VoidVisitorAdapter<Object>
|
|||
if (scope instanceof NameExpr)
|
||||
{
|
||||
NameExpr nameExpr = (NameExpr) scope;
|
||||
SimpleName simpleName1 = nameExpr.getName();
|
||||
String name1 = simpleName1.getIdentifier();
|
||||
Range range1 = nameExpr.getRange().get();
|
||||
int line1 = range1.begin.line;
|
||||
int columnStart1 = range1.begin.column;
|
||||
int columnEnd1 = range1.end.column;
|
||||
try
|
||||
{
|
||||
ResolvedValueDeclaration vd = nameExpr.resolve();
|
||||
SimpleName simpleName1 = nameExpr.getName();
|
||||
String name1 = simpleName1.getIdentifier();
|
||||
Range range1 = nameExpr.getRange().get();
|
||||
int line1 = range1.begin.line;
|
||||
int columnStart1 = range1.begin.column;
|
||||
int columnEnd1 = range1.end.column;
|
||||
if (vd.isField())
|
||||
{
|
||||
this.classFileContainer.putField(name1, new ClassFieldLocation(getOwner(), "reference", line1, columnStart1, columnEnd1 + 1));
|
||||
|
@ -122,12 +135,20 @@ public class MyVoidVisitor extends VoidVisitorAdapter<Object>
|
|||
}
|
||||
} catch (UnsolvedSymbolException ignore)
|
||||
{
|
||||
this.classFileContainer.putField(fieldName, new ClassFieldLocation(name1, "reference", line, columnStart, columnEnd + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ClassOrInterfaceType n, Object arg)
|
||||
{
|
||||
super.visit(n, arg);
|
||||
// System.err.println(n.getName().getIdentifier());
|
||||
}
|
||||
|
||||
/**
|
||||
* Visit all {@link ConstructorDeclaration}s.
|
||||
* <p>
|
||||
|
|
Loading…
Reference in New Issue
Block a user