Skip to content

Commit

Permalink
Merge branch 'dev4' into feature/renovate
Browse files Browse the repository at this point in the history
  • Loading branch information
Amejonah1200 authored Apr 14, 2024
2 parents 870e7f6 + 89c5920 commit d44478b
Show file tree
Hide file tree
Showing 12 changed files with 321 additions and 126 deletions.
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
package software.coley.recaf.services.cell.text;

import dev.xdark.blw.asm.internal.Util;
import dev.xdark.blw.code.Instruction;
import dev.xdark.blw.code.instruction.*;
import jakarta.annotation.Nonnull;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import me.darknet.assembler.helper.Names;
import me.darknet.assembler.printer.InstructionPrinter;
import me.darknet.assembler.printer.PrintContext;
import org.benf.cfr.reader.entities.annotations.ElementValue;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.*;
import org.objectweb.asm.tree.AbstractInsnNode;
import software.coley.recaf.info.*;
import software.coley.recaf.info.annotation.Annotated;
import software.coley.recaf.info.annotation.AnnotationElement;
Expand All @@ -22,6 +16,7 @@
import software.coley.recaf.info.member.MethodMember;
import software.coley.recaf.services.Service;
import software.coley.recaf.services.phantom.GeneratedPhantomWorkspaceResource;
import software.coley.recaf.ui.config.MemberDisplayFormatConfig;
import software.coley.recaf.ui.config.TextFormatConfig;
import software.coley.recaf.ui.control.tree.WorkspaceTreeCell;
import software.coley.recaf.util.BlwUtil;
Expand All @@ -32,7 +27,6 @@
import software.coley.recaf.workspace.model.bundle.*;
import software.coley.recaf.workspace.model.resource.*;

import java.util.Collections;
import java.util.List;
import java.util.Map;

Expand All @@ -47,12 +41,15 @@ public class TextProviderService implements Service {
public static final String SERVICE_ID = "cell-text";
private final TextProviderServiceConfig config;
private final TextFormatConfig formatConfig;
private final MemberDisplayFormatConfig memberFormatConfig;

@Inject
public TextProviderService(@Nonnull TextProviderServiceConfig config,
@Nonnull TextFormatConfig formatConfig) {
@Nonnull TextFormatConfig formatConfig,
@Nonnull MemberDisplayFormatConfig memberFormatConfig) {
this.config = config;
this.formatConfig = formatConfig;
this.memberFormatConfig = memberFormatConfig;
// Unlike the other services for graphics/menus, I don't see a use-case for text customization...
// Will keep the model similar to them though just in case so that it is easy to add in the future.
}
Expand Down Expand Up @@ -185,10 +182,7 @@ public TextProvider getFieldMemberTextProvider(@Nonnull Workspace workspace,
@Nonnull ClassBundle<? extends ClassInfo> bundle,
@Nonnull ClassInfo declaringClass,
@Nonnull FieldMember field) {
// TODO: Will want to provide config option for showing the type
// - name (default)
// - type + name
return () -> formatConfig.filter(field.getName());
return () -> formatConfig.filter(memberFormatConfig.getDisplay(field), false, true, true);
}

/**
Expand All @@ -211,11 +205,7 @@ public TextProvider getMethodMemberTextProvider(@Nonnull Workspace workspace,
@Nonnull ClassBundle<? extends ClassInfo> bundle,
@Nonnull ClassInfo declaringClass,
@Nonnull MethodMember method) {
// TODO: Will want to provide config option for showing the descriptor
// - hidden (default)
// - raw
// - simple names
return () -> formatConfig.filter(method.getName());
return () -> formatConfig.filter(memberFormatConfig.getDisplay(method), false, true, true);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package software.coley.recaf.ui.config;

import jakarta.annotation.Nonnull;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import org.objectweb.asm.Type;
import software.coley.observables.ObservableObject;
import software.coley.recaf.config.BasicConfigContainer;
import software.coley.recaf.config.BasicConfigValue;
import software.coley.recaf.config.ConfigGroups;
import software.coley.recaf.info.member.ClassMember;
import software.coley.recaf.info.member.FieldMember;
import software.coley.recaf.info.member.MethodMember;
import software.coley.recaf.util.Types;

/**
* Config for {@link ClassMember} display.
*
* @author Matt Coley
*/
@ApplicationScoped
public class MemberDisplayFormatConfig extends BasicConfigContainer {
public static final String ID = "member-format";
private final ObservableObject<Display> nameTypeDisplay = new ObservableObject<>(Display.NAME_ONLY);

@Inject
public MemberDisplayFormatConfig() {
super(ConfigGroups.SERVICE_UI, ID + CONFIG_SUFFIX);
// Add values
addValue(new BasicConfigValue<>("name-type-display", Display.class, nameTypeDisplay));
}

@Nonnull
public ObservableObject<Display> getNameTypeDisplay() {
return nameTypeDisplay;
}

@Nonnull
public String getDisplay(@Nonnull ClassMember member) {
if (member instanceof FieldMember field)
return getDisplay(field);
else if (member instanceof MethodMember method)
return getDisplay(method);
throw new IllegalStateException("Member not field or method: " + member);
}

@Nonnull
public String getDisplay(@Nonnull FieldMember member) {
return switch (nameTypeDisplay.getValue()) {
case NAME_ONLY -> member.getName();
case NAME_AND_RAW_DESCRIPTOR -> member.getName() + " " + member.getDescriptor();
case NAME_AND_PRETTY_DESCRIPTOR ->
member.getName() + " " + Types.pretty(Type.getType(member.getDescriptor()));
};
}

@Nonnull
public String getDisplay(@Nonnull MethodMember member) {
return switch (nameTypeDisplay.getValue()) {
case NAME_ONLY -> member.getName();
case NAME_AND_RAW_DESCRIPTOR -> member.getName() + member.getDescriptor();
case NAME_AND_PRETTY_DESCRIPTOR ->
member.getName() + " " + Types.pretty(Type.getMethodType(member.getDescriptor()));
};
}

public enum Display {
NAME_ONLY,
NAME_AND_RAW_DESCRIPTOR,
NAME_AND_PRETTY_DESCRIPTOR
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public ObservableBoolean getDoEscape() {
* @return {@code true} to shorten path text with {@link #filter(String)}.
*/
@Nonnull
public ObservableBoolean getDoShorten() {
public ObservableBoolean getDoShortenPaths() {
return shorten;
}

Expand All @@ -64,10 +64,26 @@ public ObservableInteger getMaxLength() {
* @return Filtered text based on current config.
*/
public String filter(@Nullable String string) {
return filter(string, true, true, true);
}

/**
* @param string
* Some text to filter.
* @param shortenPath
* Apply path shortening filtering.
* @param escape
* Apply escaping.
* @param maxLength
* Apply max length cap.
*
* @return Filtered text based on current config.
*/
public String filter(@Nullable String string, boolean shortenPath, boolean escape, boolean maxLength) {
if (string == null) return null;
string = filterShorten(string);
string = filterEscape(string);
string = filterMaxLength(string);
if (shortenPath) string = filterShorten(string);
if (escape) string = filterEscape(string);
if (maxLength) string = filterMaxLength(string);
return string;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,17 @@ public List<Problem> getProblemsByLevel(ProblemLevel level) {
return getProblems(p -> p.getLevel() == level);
}

/**
* @param phase
* Problem phase to filter problems by.
*
* @return List of problems matching the given phase.
*/
@Nonnull
public List<Problem> getProblemsByPhase(ProblemPhase phase) {
return getProblems(p -> p.getPhase() == phase);
}

/**
* @param filter
* Filter to pass problems through.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.slf4j.Logger;
import software.coley.recaf.analytics.logging.Logging;
import software.coley.recaf.util.ReflectUtil;
import software.coley.recaf.util.Unchecked;

import java.lang.reflect.Field;
import java.util.Collections;
Expand All @@ -33,6 +34,7 @@ public class FilterableTreeItem<T> extends TreeItem<T> {
private static final Field CHILDREN_FIELD;
private static final Logger logger = Logging.get(FilterableTreeItem.class);
private final ObservableList<TreeItem<T>> sourceChildren = FXCollections.observableArrayList();
private final ObjectProperty<TreeItem<T>> sourceParent = new SimpleObjectProperty<>();
private final ObjectProperty<Predicate<TreeItem<T>>> predicate = new SimpleObjectProperty<>();

protected FilterableTreeItem() {
Expand Down Expand Up @@ -62,6 +64,14 @@ public ObservableList<TreeItem<T>> getChildren() {
return super.getChildren();
}

/**
* @return Source parent, ignoring filtering.
*/
@Nonnull
public ObjectProperty<TreeItem<T>> sourceParentProperty() {
return sourceParent;
}

/**
* @return {@code true} when the item MUST be shown.
*/
Expand Down Expand Up @@ -135,6 +145,8 @@ public void addAndSortChild(@Nonnull TreeItem<T> item) {
index = -(index + 1);
sourceChildren.add(index, item);
}
if (item instanceof FilterableTreeItem<?> filterableItem)
filterableItem.sourceParent.set(Unchecked.cast(this));
}
}

Expand All @@ -146,6 +158,8 @@ public void addAndSortChild(@Nonnull TreeItem<T> item) {
*/
protected void addPreSortedChild(@Nonnull TreeItem<T> item) {
sourceChildren.add(item);
if (item instanceof FilterableTreeItem<?> filterableItem)
filterableItem.sourceParent.set(Unchecked.cast(this));
}

/**
Expand All @@ -159,6 +173,8 @@ protected void addPreSortedChild(@Nonnull TreeItem<T> item) {
*/
public boolean removeSourceChild(@Nonnull TreeItem<T> child) {
synchronized (sourceChildren) {
if (child instanceof FilterableTreeItem<?> filterableItem)
filterableItem.sourceParent.set(null);
return sourceChildren.remove(child);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package software.coley.recaf.ui.control.tree;

import jakarta.annotation.Nonnull;
import javafx.scene.control.TextField;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
Expand All @@ -24,7 +25,7 @@ public class TreeFiltering {
* Assumed that tree contents are {@link FilterableTreeItem}.
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public static void install(TextField filter, TreeView<?> tree) {
public static void install(@Nonnull TextField filter, @Nonnull TreeView<?> tree) {
NodeEvents.addKeyPressHandler(filter, e -> {
if (e.getCode() == KeyCode.ESCAPE) {
filter.clear();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package software.coley.recaf.ui.control.tree;

import jakarta.annotation.Nonnull;
import jakarta.annotation.Nullable;
import javafx.scene.control.MultipleSelectionModel;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
Expand All @@ -16,7 +17,7 @@ public class TreeItems {
* Expand all parents to this item.
*/
public static void expandParents(@Nonnull TreeItem<?> item) {
while ((item = item.getParent()) != null)
while ((item = getParent(item)) != null)
item.setExpanded(true);
}

Expand Down Expand Up @@ -62,4 +63,18 @@ private static void recurseClose(@Nonnull TreeItem<?> item) {
item.getChildren().forEach(TreeItems::recurseClose);
}
}

/**
* @param item
* Tree item to get parent of.
*
* @return Parent tree item.
*/
@Nullable
private static TreeItem<?> getParent(@Nonnull TreeItem<?> item) {
TreeItem<?> parent = item.getParent();
if (parent == null && item instanceof FilterableTreeItem<?> filterableItem)
parent = filterableItem.sourceParentProperty().get();
return parent;
}
}
Loading

0 comments on commit d44478b

Please sign in to comment.