Skip to content

Commit e9570b0

Browse files
committed
Consolidate embedded resource path generation edge case to fix UI breakages with embedded contents
1 parent ca62ff4 commit e9570b0

File tree

5 files changed

+40
-15
lines changed

5 files changed

+40
-15
lines changed

recaf-core/src/main/java/software/coley/recaf/path/PathNode.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ default PathNode withCurrentWorkspaceContent() {
7070
* @return {@code true} when the other path has the same {@link #getValue() local value}.
7171
*/
7272
default boolean hasEqualOrChildValue(@Nonnull PathNode<?> other) {
73-
return this == other || getValue().equals(other.getValue());
73+
V value = getValue();
74+
Object otherValue = other.getValue();
75+
return this == other || value == otherValue || value.equals(otherValue);
7476
}
7577

7678
/**

recaf-core/src/main/java/software/coley/recaf/path/PathNodes.java

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,7 @@ public static WorkspacePathNode workspacePath(@Nonnull Workspace workspace) {
5757
@Nonnull
5858
public static ResourcePathNode resourcePath(@Nonnull Workspace workspace,
5959
@Nonnull WorkspaceResource resource) {
60-
// Base case, resource is top-level in the workspace.
61-
WorkspaceResource containingResource = resource.getContainingResource();
62-
if (containingResource == null)
63-
return workspacePath(workspace).child(resource);
64-
65-
// Resource is embedded, so we need to represent the path a bit differently.
66-
WorkspaceResource rootResource = containingResource;
67-
while (rootResource.getContainingResource() != null)
68-
rootResource = rootResource.getContainingResource();
69-
return workspacePath(workspace).child(rootResource).embeddedChildContainer().child(resource);
60+
return workspacePath(workspace).child(resource);
7061
}
7162

7263
/**

recaf-core/src/main/java/software/coley/recaf/path/ResourcePathNode.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,29 @@ public EmbeddedResourceContainerPathNode embeddedChildContainer() {
9090
*/
9191
public boolean isPrimary() {
9292
PathNode<Workspace> parent = getParent();
93-
if (parent == null) return false;
93+
if (parent == null)
94+
return false;
9495
return parent.getValue().getPrimaryResource() == getValue();
9596
}
9697

98+
/**
99+
* @return {@code true} when this resource node, wraps the primary resource of a workspace or any resource embedded in the primary resource.
100+
*/
101+
public boolean isPrimaryOrEmbeddedInPrimary() {
102+
PathNode<Workspace> parent = getParent();
103+
if (parent == null)
104+
return false;
105+
Workspace workspace = parent.getValue();
106+
WorkspaceResource primary = workspace.getPrimaryResource();
107+
WorkspaceResource resource = getValue();
108+
while (resource != null) {
109+
if (primary == resource)
110+
return true;
111+
resource = resource.getContainingResource();
112+
}
113+
return false;
114+
}
115+
97116
@Nonnull
98117
@Override
99118
public Set<String> directParentTypeIds() {

recaf-core/src/main/java/software/coley/recaf/path/WorkspacePathNode.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,24 @@ public WorkspacePathNode(@Nonnull Workspace value) {
3232
* @param resource
3333
* Resource to wrap into node.
3434
*
35-
* @return Path node of resource, with the current workspace as parent.
35+
* @return Path node of resource, with the current workspace as parent,
36+
* or a {@link EmbeddedResourceContainerPathNode} if the passed resource is an embedded resource.
3637
*/
3738
@Nonnull
3839
public ResourcePathNode child(@Nonnull WorkspaceResource resource) {
39-
return new ResourcePathNode(this, resource);
40+
// Base case, resource is top-level in the workspace.
41+
WorkspaceResource containingResource = resource.getContainingResource();
42+
if (containingResource == null)
43+
return new ResourcePathNode(this, resource);
44+
45+
// Resource is embedded, so we need to represent the path a bit differently.
46+
// - Note: We flatten the representation of embedded resources here.
47+
WorkspaceResource rootResource = containingResource;
48+
while (rootResource.getContainingResource() != null)
49+
rootResource = rootResource.getContainingResource();
50+
return new ResourcePathNode(this, rootResource)
51+
.embeddedChildContainer()
52+
.child(resource);
4053
}
4154

4255
@Nonnull

recaf-core/src/main/java/software/coley/recaf/services/inheritance/InheritanceGraph.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ private InheritanceVertex createVertex(@Nullable String name) {
415415

416416
// Map class to vertex.
417417
ResourcePathNode resourcePath = result.getPathOfType(WorkspaceResource.class);
418-
boolean isPrimary = resourcePath != null && resourcePath.isPrimary();
418+
boolean isPrimary = resourcePath != null && resourcePath.isPrimaryOrEmbeddedInPrimary();
419419
ClassInfo info = result.getValue();
420420
return new InheritanceVertex(info, this::getVertex, this::getDirectChildren, isPrimary);
421421
}

0 commit comments

Comments
 (0)