Fix up the post-default interface generation

This commit is contained in:
Ben Gruver 2016-09-26 23:29:55 -07:00
parent 37f5436932
commit ab20c37fd0
2 changed files with 68 additions and 41 deletions

View File

@ -166,6 +166,7 @@ public class ClassProto implements TypeProto {
} }
} }
} catch (UnresolvedClassException ex) { } catch (UnresolvedClassException ex) {
interfaces.put(type, null);
unresolvedInterfaces.add(type); unresolvedInterfaces.add(type);
interfacesFullyResolved = false; interfacesFullyResolved = false;
} }
@ -230,11 +231,21 @@ public class ClassProto implements TypeProto {
for (String interfaceType: getClassDef().getInterfaces()) { for (String interfaceType: getClassDef().getInterfaces()) {
if (!interfaces.containsKey(interfaceType)) { if (!interfaces.containsKey(interfaceType)) {
ClassProto interfaceProto = (ClassProto)classPath.getClass(interfaceType); ClassProto interfaceProto = (ClassProto)classPath.getClass(interfaceType);
try {
for (Entry<String, ClassDef> entry: interfaceProto.getInterfaces().entrySet()) { for (Entry<String, ClassDef> entry: interfaceProto.getInterfaces().entrySet()) {
if (!interfaces.containsKey(entry.getKey())) { if (!interfaces.containsKey(entry.getKey())) {
interfaces.put(entry.getKey(), entry.getValue()); interfaces.put(entry.getKey(), entry.getValue());
} }
} }
} catch (UnresolvedClassException ex) {
interfaces.put(interfaceType, null);
unresolvedInterfaces.add(interfaceType);
interfacesFullyResolved = false;
}
if (!interfaceProto.interfacesFullyResolved) {
unresolvedInterfaces.addAll(interfaceProto.getUnresolvedInterfaces());
interfacesFullyResolved = false;
}
try { try {
ClassDef interfaceDef = classPath.getClassDef(interfaceType); ClassDef interfaceDef = classPath.getClassDef(interfaceType);
interfaces.put(interfaceType, interfaceDef); interfaces.put(interfaceType, interfaceDef);
@ -246,6 +257,7 @@ public class ClassProto implements TypeProto {
} }
} }
} catch (UnresolvedClassException ex) { } catch (UnresolvedClassException ex) {
interfaces.put(type, null);
unresolvedInterfaces.add(type); unresolvedInterfaces.add(type);
interfacesFullyResolved = false; interfacesFullyResolved = false;
} }

View File

@ -32,8 +32,10 @@
package org.jf.dexlib2.analysis; package org.jf.dexlib2.analysis;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import junit.framework.Assert; import junit.framework.Assert;
import org.jf.dexlib2.Opcodes; import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.iface.ClassDef;
import org.jf.dexlib2.immutable.ImmutableDexFile; import org.jf.dexlib2.immutable.ImmutableDexFile;
import org.junit.Test; import org.junit.Test;
@ -51,11 +53,12 @@ public class CommonSuperclassTest {
// fivetwothree // fivetwothree
// fivethree // fivethree
private final ClassPath classPath; private final ClassPath oldClassPath;
private final ClassPath newClassPath;
public CommonSuperclassTest() throws IOException { public CommonSuperclassTest() throws IOException {
classPath = new ClassPath(new DexClassProvider(new ImmutableDexFile(Opcodes.getDefault(), ImmutableSet<ClassDef> classes = ImmutableSet.of(
ImmutableSet.of(
TestUtils.makeClassDef("Ljava/lang/Object;", null), TestUtils.makeClassDef("Ljava/lang/Object;", null),
TestUtils.makeClassDef("Ltest/one;", "Ljava/lang/Object;"), TestUtils.makeClassDef("Ltest/one;", "Ljava/lang/Object;"),
TestUtils.makeClassDef("Ltest/two;", "Ljava/lang/Object;"), TestUtils.makeClassDef("Ltest/two;", "Ljava/lang/Object;"),
@ -88,11 +91,14 @@ public class CommonSuperclassTest {
"Liface/sub4;"), "Liface/sub4;"),
TestUtils.makeClassDef("Liface/classsubsub4;", "Liface/classsub4;"), TestUtils.makeClassDef("Liface/classsubsub4;", "Liface/classsub4;"),
TestUtils.makeClassDef("Liface/classsub1234;", "Ljava/lang/Object;", "Liface/sub1;", TestUtils.makeClassDef("Liface/classsub1234;", "Ljava/lang/Object;", "Liface/sub1;",
"Liface/sub2;", "Liface/sub3;", "Liface/sub4;") "Liface/sub2;", "Liface/sub3;", "Liface/sub4;"));
))));
oldClassPath = new ClassPath(new DexClassProvider(new ImmutableDexFile(Opcodes.getDefault(), classes)));
newClassPath = new ClassPath(Lists.newArrayList(new DexClassProvider(
new ImmutableDexFile(Opcodes.forArtVersion(72), classes))), true, 72);
} }
public void superclassTest(String commonSuperclass, public void superclassTest(ClassPath classPath, String commonSuperclass,
String type1, String type2) { String type1, String type2) {
TypeProto commonSuperclassProto = classPath.getClass(commonSuperclass); TypeProto commonSuperclassProto = classPath.getClass(commonSuperclass);
TypeProto type1Proto = classPath.getClass(type1); TypeProto type1Proto = classPath.getClass(type1);
@ -102,6 +108,11 @@ public class CommonSuperclassTest {
Assert.assertSame(commonSuperclassProto, type2Proto.getCommonSuperclass(type1Proto)); Assert.assertSame(commonSuperclassProto, type2Proto.getCommonSuperclass(type1Proto));
} }
public void superclassTest(String commonSuperclass, String type1, String type2) {
superclassTest(oldClassPath, commonSuperclass, type1, type2);
superclassTest(newClassPath, commonSuperclass, type1, type2);
}
@Test @Test
public void testGetCommonSuperclass() throws IOException { public void testGetCommonSuperclass() throws IOException {
String object = "Ljava/lang/Object;"; String object = "Ljava/lang/Object;";
@ -131,7 +142,11 @@ public class CommonSuperclassTest {
// same value, but different object // same value, but different object
Assert.assertEquals( Assert.assertEquals(
onetwo, onetwo,
classPath.getClass(onetwo).getCommonSuperclass(new ClassProto(classPath, onetwo)).getType()); oldClassPath.getClass(onetwo).getCommonSuperclass(new ClassProto(oldClassPath, onetwo)).getType());
Assert.assertEquals(
onetwo,
newClassPath.getClass(onetwo).getCommonSuperclass(new ClassProto(newClassPath, onetwo)).getType());
// other object is superclass // other object is superclass
superclassTest(object, object, one); superclassTest(object, object, one);