Skip to content

Commit

Permalink
Sort call graph tree items by natural order
Browse files Browse the repository at this point in the history
  • Loading branch information
Col-E committed Jun 12, 2024
1 parent 06987b0 commit 8ffd8b4
Showing 1 changed file with 37 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import net.greypanther.natsort.CaseInsensitiveSimpleNaturalComparator;
import org.kordamp.ikonli.carbonicons.CarbonIcons;
import software.coley.collections.Unchecked;
import software.coley.recaf.info.ClassInfo;
Expand All @@ -32,6 +33,7 @@
import software.coley.recaf.services.navigation.UpdatableNavigable;
import software.coley.recaf.services.text.TextFormatConfig;
import software.coley.recaf.ui.control.FontIconView;
import software.coley.recaf.util.CollectionUtil;
import software.coley.recaf.util.FxThreadUtil;
import software.coley.recaf.util.Lang;
import software.coley.recaf.workspace.model.Workspace;
Expand All @@ -40,7 +42,6 @@
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
* Tree display of method calls.
Expand Down Expand Up @@ -103,12 +104,12 @@ public Collection<Navigable> getNavigableChildren() {

@Override
public void disable() {
// TODO: Cleanup
graphTreeView.setRoot(null);
}

@Override
public void requestFocus(@Nonnull ClassMember member) {
// TODO: Select method
// no-op
}

public enum CallGraphMode {
Expand All @@ -125,13 +126,37 @@ public enum CallGraphMode {
/**
* Item of a class in the hierarchy.
*/
private static class CallGraphItem extends TreeItem<MethodMember> {
private static class CallGraphItem extends TreeItem<MethodMember> implements Comparable<CallGraphItem> {
private static final Comparator<String> comparator = CaseInsensitiveSimpleNaturalComparator.getInstance();
boolean recursive;

private CallGraphItem(@Nonnull MethodMember method, boolean recursive) {
super(method);
this.recursive = recursive;
}

@Nullable
private ClassInfo getDeclaringClass() {
return getValue().getDeclaringClass();
}

@Override
public int compareTo(CallGraphItem o) {
// We want the tree display to have items in sorted order by
// package > class > method-name > method-args
int cmp = 0;
MethodMember method = getValue();
MethodMember otherMethod = o.getValue();
ClassInfo declaringClass = getDeclaringClass();
ClassInfo otherDeclaringClass = o.getDeclaringClass();
if (declaringClass != null)
cmp = comparator.compare(declaringClass.getName(), otherDeclaringClass.getName());
if (cmp == 0)
cmp = comparator.compare(method.getName(), otherMethod.getName());
if (cmp == 0)
cmp = comparator.compare(method.getDescriptor(), otherMethod.getDescriptor());
return cmp;
}
}

/**
Expand Down Expand Up @@ -181,11 +206,13 @@ protected void updateItem(MethodMember method, boolean empty) {
else methodText.setFill(Color.YELLOW);

// Layout
HBox box = new HBox(configurationService.graphicOf(methodPath),
new TextFlow(classText, new Label("#"), methodText, new Label(method.getDescriptor())));
TextFlow textFlow = new TextFlow(classText, new Label("#"), methodText, new Label(method.getDescriptor()));
HBox box = new HBox(configurationService.graphicOf(methodPath), textFlow);
box.setSpacing(5);
if (getTreeItem() instanceof CallGraphItem && ((CallGraphItem) getTreeItem()).recursive)
if (getTreeItem() instanceof CallGraphItem i && i.recursive) {
box.getChildren().add(new FontIconView(CarbonIcons.CODE_REFERENCE));
box.setOpacity(0.4);
}
setGraphic(box);

// Context menu support
Expand Down Expand Up @@ -259,21 +286,16 @@ private CallGraphItem buildCallGraph(@Nonnull MethodMember rootMethod, @Nonnull
depth++;
final MethodVertex vertex = callGraph.getVertex(item.getValue());
if (vertex != null) {
final List<CallGraphItem> newTodo = Stream.concat(
childrenGetter.apply(vertex)
.stream(),
mode == CallGraphMode.CALLERS ?
Stream.empty() :
vertex.getCallers().stream()
)
final List<CallGraphItem> newTodo = childrenGetter.apply(vertex).stream()
.filter(c -> c.getResolvedMethod() != null)
.map(c -> {
MethodMember cm = c.getResolvedMethod();
return new CallGraphItem(cm, visitedMethods.contains(cm));
})
.filter(i -> {
if (i.getValue() == null) return false;
item.getChildren().add(i);
int insert = CollectionUtil.sortedInsertIndex(Unchecked.cast(item.getChildren()), i);
item.getChildren().add(insert, i);
return !i.recursive;
}).collect(Collectors.toList());
if (!newTodo.isEmpty() && depth < MAX_TREE_DEPTH) {
Expand Down

0 comments on commit 8ffd8b4

Please sign in to comment.