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> { ...@@ -84,11 +84,13 @@ public class JPackage extends JNode implements Comparable<JPackage> {
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o) {
if (o == null || getClass() != o.getClass()) return false; return true;
JPackage jPackage = (JPackage) o; }
if (!name.equals(jPackage.name)) return false; if (o == null || getClass() != o.getClass()) {
return true; return false;
}
return name.equals(((JPackage) o).name);
} }
@Override @Override
......
...@@ -10,7 +10,7 @@ import java.io.File; ...@@ -10,7 +10,7 @@ import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.IdentityHashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -47,6 +47,12 @@ public class JRoot extends JNode { ...@@ -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) { List<JPackage> getHierarchyPackages(List<JavaPackage> packages) {
Map<String, JPackage> pkgMap = new HashMap<String, JPackage>(); Map<String, JPackage> pkgMap = new HashMap<String, JPackage>();
for (JavaPackage pkg : packages) { for (JavaPackage pkg : packages) {
...@@ -63,11 +69,11 @@ public class JRoot extends JNode { ...@@ -63,11 +69,11 @@ public class JRoot extends JNode {
pkg.getInnerPackages().addAll(innerPkg.getInnerPackages()); pkg.getInnerPackages().addAll(innerPkg.getInnerPackages());
pkg.getClasses().addAll(innerPkg.getClasses()); pkg.getClasses().addAll(innerPkg.getClasses());
pkg.setName(pkg.getName() + "." + innerPkg.getName()); pkg.setName(pkg.getName() + "." + innerPkg.getName());
innerPkg.getInnerPackages().clear(); innerPkg.getInnerPackages().clear();
innerPkg.getClasses().clear(); innerPkg.getClasses().clear();
repeat = true; repeat = true;
pkgMap.remove(innerPkg.getName());
break; break;
} }
} }
...@@ -80,14 +86,16 @@ public class JRoot extends JNode { ...@@ -80,14 +86,16 @@ public class JRoot extends JNode {
it.remove(); 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()) { for (JPackage pkg : pkgMap.values()) {
inners.addAll(pkg.getInnerPackages()); innerPackages.addAll(pkg.getInnerPackages());
} }
// find root packages
List<JPackage> rootPkgs = new ArrayList<JPackage>(); List<JPackage> rootPkgs = new ArrayList<JPackage>();
for (JPackage pkg : pkgMap.values()) { for (JPackage pkg : pkgMap.values()) {
if (!inners.contains(pkg)) { if (!innerPackages.contains(pkg)) {
rootPkgs.add(pkg); rootPkgs.add(pkg);
} }
} }
......
...@@ -8,10 +8,10 @@ import jadx.api.JavaPackage; ...@@ -8,10 +8,10 @@ import jadx.api.JavaPackage;
import jadx.core.dex.nodes.ClassNode; import jadx.core.dex.nodes.ClassNode;
import jadx.gui.JadxWrapper; import jadx.gui.JadxWrapper;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
...@@ -19,25 +19,84 @@ import static org.mockito.Mockito.mock; ...@@ -19,25 +19,84 @@ import static org.mockito.Mockito.mock;
public class JRootTest { 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 @Test
public void testHierarchyPackages() { public void testHierarchyPackages() {
String pkgName = "a.b.c.d.e"; String pkgName = "a.b.c.d.e";
JadxWrapper wrapper = mock(JadxWrapper.class); List<JavaPackage> packages = Arrays.asList(newPkg(pkgName));
JRoot root = new JRoot(wrapper); List<JPackage> out = root.getHierarchyPackages(packages);
JavaClass cls = Factory.newClass(new Decompiler(mock(IJadxArgs.class)), mock(ClassNode.class)); assertEquals(out.size(), 1);
JavaPackage pkg = Factory.newPackage(pkgName, Arrays.asList(cls)); JPackage jpkg = out.get(0);
assertEquals(jpkg.getName(), pkgName);
assertEquals(jpkg.getClasses().size(), 1);
}
List<JavaPackage> packages = new ArrayList<JavaPackage>(); @Test
packages.add(pkg); 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); List<JPackage> out = root.getHierarchyPackages(packages);
assertEquals(out.size(), 1); assertEquals(out.size(), 1);
JPackage jpkg = out.get(0); JPackage jpkg = out.get(0);
assertEquals(jpkg.getName(), pkgName); assertEquals(jpkg.getName(), "a.b");
assertEquals(jpkg.getClasses().size(), 1); 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