Commit 438b3b50 authored by Skylot's avatar Skylot

gui: fix missed nodes in hierarchical packages tree

parent 6bac5c16
......@@ -84,11 +84,13 @@ public class JPackage extends JNode implements Comparable<JPackage> {
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
JPackage jPackage = (JPackage) o;
if (!name.equals(jPackage.name)) return false;
return true;
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
return name.equals(((JPackage) o).name);
}
@Override
......
......@@ -10,7 +10,7 @@ import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
......@@ -47,6 +47,12 @@ public class JRoot extends JNode {
}
}
/**
* Convert packages list to hierarchical packages representation
*
* @param packages input packages list
* @return root packages
*/
List<JPackage> getHierarchyPackages(List<JavaPackage> packages) {
Map<String, JPackage> pkgMap = new HashMap<String, JPackage>();
for (JavaPackage pkg : packages) {
......@@ -63,11 +69,11 @@ public class JRoot extends JNode {
pkg.getInnerPackages().addAll(innerPkg.getInnerPackages());
pkg.getClasses().addAll(innerPkg.getClasses());
pkg.setName(pkg.getName() + "." + innerPkg.getName());
innerPkg.getInnerPackages().clear();
innerPkg.getClasses().clear();
repeat = true;
pkgMap.remove(innerPkg.getName());
break;
}
}
......@@ -80,14 +86,16 @@ public class JRoot extends JNode {
it.remove();
}
}
// find root packages
Set<JPackage> inners = new HashSet<JPackage>();
// use identity set for collect inner packages
Set<JPackage> innerPackages = Collections.newSetFromMap(new IdentityHashMap<JPackage,Boolean>());
for (JPackage pkg : pkgMap.values()) {
inners.addAll(pkg.getInnerPackages());
innerPackages.addAll(pkg.getInnerPackages());
}
// find root packages
List<JPackage> rootPkgs = new ArrayList<JPackage>();
for (JPackage pkg : pkgMap.values()) {
if (!inners.contains(pkg)) {
if (!innerPackages.contains(pkg)) {
rootPkgs.add(pkg);
}
}
......
......@@ -8,10 +8,10 @@ import jadx.api.JavaPackage;
import jadx.core.dex.nodes.ClassNode;
import jadx.gui.JadxWrapper;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
......@@ -19,25 +19,84 @@ import static org.mockito.Mockito.mock;
public class JRootTest {
private JRoot root;
private Decompiler decompiler;
@Before
public void init() {
root = new JRoot(mock(JadxWrapper.class));
decompiler = new Decompiler(mock(IJadxArgs.class));
}
@Test
public void testHierarchyPackages() {
String pkgName = "a.b.c.d.e";
JadxWrapper wrapper = mock(JadxWrapper.class);
JRoot root = new JRoot(wrapper);
List<JavaPackage> packages = Arrays.asList(newPkg(pkgName));
List<JPackage> out = root.getHierarchyPackages(packages);
JavaClass cls = Factory.newClass(new Decompiler(mock(IJadxArgs.class)), mock(ClassNode.class));
JavaPackage pkg = Factory.newPackage(pkgName, Arrays.asList(cls));
assertEquals(out.size(), 1);
JPackage jpkg = out.get(0);
assertEquals(jpkg.getName(), pkgName);
assertEquals(jpkg.getClasses().size(), 1);
}
List<JavaPackage> packages = new ArrayList<JavaPackage>();
packages.add(pkg);
@Test
public void testHierarchyPackages2() {
List<JavaPackage> packages = Arrays.asList(
newPkg("a.b"),
newPkg("a.c"),
newPkg("a.d")
);
List<JPackage> out = root.getHierarchyPackages(packages);
assertEquals(out.size(), 1);
JPackage jpkg = out.get(0);
assertEquals(jpkg.getName(), "a");
assertEquals(jpkg.getClasses().size(), 0);
assertEquals(jpkg.getInnerPackages().size(), 3);
}
@Test
public void testHierarchyPackages3() {
List<JavaPackage> packages = Arrays.asList(
newPkg("a.b.p1"),
newPkg("a.b.p2"),
newPkg("a.b.p3")
);
List<JPackage> out = root.getHierarchyPackages(packages);
assertEquals(out.size(), 1);
JPackage jpkg = out.get(0);
assertEquals(jpkg.getName(), pkgName);
assertEquals(jpkg.getClasses().size(), 1);
assertEquals(jpkg.getName(), "a.b");
assertEquals(jpkg.getClasses().size(), 0);
assertEquals(jpkg.getInnerPackages().size(), 3);
}
@Test
public void testHierarchyPackages4() {
List<JavaPackage> packages = Arrays.asList(
newPkg("a.p1"),
newPkg("a.b.c.p2"),
newPkg("a.b.c.p3"),
newPkg("d.e"),
newPkg("d.f.a")
);
List<JPackage> out = root.getHierarchyPackages(packages);
assertEquals(out.size(), 2);
assertEquals(out.get(0).getName(), "a");
assertEquals(out.get(0).getInnerPackages().size(), 2);
assertEquals(out.get(1).getName(), "d");
assertEquals(out.get(1).getInnerPackages().size(), 2);
}
private JavaPackage newPkg(String name) {
return Factory.newPackage(name, Arrays.asList(newClass()));
}
private JavaClass newClass() {
return Factory.newClass(decompiler, mock(ClassNode.class));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment