Skip to content

Commit

Permalink
don't distinguish explicitly between incomplete/complete superclassesof
Browse files Browse the repository at this point in the history
  • Loading branch information
swissiety committed Nov 9, 2023
1 parent f684a98 commit cc8a35a
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ protected Stream<MethodSignature> resolveAllStaticInitializerCallsFromSourceMeth
classType ->
Stream.concat(
Stream.of(classType),
view.getTypeHierarchy().incompleteSuperClassesOf(classType).stream()))
view.getTypeHierarchy().superClassesOf(classType).stream()))
.filter(Objects::nonNull)
.map(classType -> view.getMethod(classType.getStaticInitializer()))
.filter(Optional::isPresent)
Expand All @@ -291,7 +291,7 @@ protected final <T extends Method> T findMethodInHierarchy(
if (optSc.isPresent()) {
SootClass<?> sc = optSc.get();

List<ClassType> superClasses = view.getTypeHierarchy().incompleteSuperClassesOf(sc.getType());
List<ClassType> superClasses = view.getTypeHierarchy().superClassesOf(sc.getType());
Set<ClassType> interfaces = view.getTypeHierarchy().implementedInterfacesOf(sc.getType());
superClasses.addAll(interfaces);

Expand Down Expand Up @@ -364,7 +364,7 @@ public CallGraph addClass(@Nonnull CallGraph oldCallGraph, @Nonnull JavaClassTyp
processWorkList(view, workList, processed, updated);

// Step 2: Add edges from old methods to methods overridden in the new class
List<ClassType> superClasses = view.getTypeHierarchy().incompleteSuperClassesOf(classType);
List<ClassType> superClasses = view.getTypeHierarchy().superClassesOf(classType);
Set<ClassType> implementedInterfaces =
view.getTypeHierarchy().implementedInterfacesOf(classType);
Stream<ClassType> superTypes =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,7 @@ public static boolean canDispatch(
private static List<SootClass<?>> findSuperClassesInclusive(
View<? extends SootClass<?>> view, ClassType classType) {
return Stream.concat(
Stream.of(classType),
view.getTypeHierarchy().incompleteSuperClassesOf(classType).stream())
Stream.of(classType), view.getTypeHierarchy().superClassesOf(classType).stream())
.flatMap(t -> view.getClass(t).map(Stream::of).orElseGet(Stream::empty))
.collect(Collectors.toList());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ default boolean isSubtype(@Nonnull Type supertype, @Nonnull Type potentialSubtyp
return (supertypeName.equals("java.lang.Object")
&& !potentialSubtypeName.equals("java.lang.Object"))
|| supertype.equals(superClassOf((ClassType) potentialSubtype))
|| incompleteSuperClassesOf((ClassType) potentialSubtype).contains(supertype)
|| superClassesOf((ClassType) potentialSubtype).contains(supertype)
|| implementedInterfacesOf((ClassType) potentialSubtype).contains(supertype);
} else if (potentialSubtype instanceof ArrayType) {
// Arrays are subtypes of java.lang.Object, java.io.Serializable and java.lang.Cloneable
Expand All @@ -169,27 +169,12 @@ default boolean isSubtype(@Nonnull Type supertype, @Nonnull Type potentialSubtyp
}
}

/**
* Returns all superclasses of <code>classType</code> up to <code>java.lang.Object</code>, which
* will be the last entry in the list. i.e. its ordered from bottom level to top level.
*/
@Nonnull
default List<ClassType> superClassesOf(@Nonnull ClassType classType) {
List<ClassType> superClasses = new ArrayList<>();
ClassType currentSuperClass = superClassOf(classType);
while (currentSuperClass != null) {
superClasses.add(currentSuperClass);
currentSuperClass = superClassOf(currentSuperClass);
}
return superClasses;
}

/**
* Returns all superclasses of <code>classType</code> up to <code>java.lang.Object</code>, which
* will be the last entry in the list, or till one of the superclasses is not contained in view.
*/
@Nonnull
default List<ClassType> incompleteSuperClassesOf(@Nonnull ClassType classType) {
default List<ClassType> superClassesOf(@Nonnull ClassType classType) {
List<ClassType> superClasses = new ArrayList<>();
ClassType currentSuperClass = null;
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ protected Stream<Vertex> directSuperClassOf(@Nonnull Vertex classVertex) {
public Set<ClassType> directlyImplementedInterfacesOf(@Nonnull ClassType classType) {
Vertex vertex = lazyScanResult.get().typeToVertex.get(classType);
if (vertex == null) {
throw new IllegalStateException("Could not find '" + classType + "' in hierarchy.");
throw new IllegalArgumentException("Could not find '" + classType + "' in hierarchy.");

Check warning on line 193 in sootup.core/src/main/java/sootup/core/typehierarchy/ViewTypeHierarchy.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/typehierarchy/ViewTypeHierarchy.java#L193

Added line #L193 was not covered by tests
}
if (vertex.type != VertexType.Class) {
throw new IllegalArgumentException(classType + " is not a class.");
Expand All @@ -204,7 +204,7 @@ public Set<ClassType> directlyImplementedInterfacesOf(@Nonnull ClassType classTy
public Set<ClassType> directlyExtendedInterfacesOf(@Nonnull ClassType interfaceType) {
Vertex vertex = lazyScanResult.get().typeToVertex.get(interfaceType);
if (vertex == null) {
throw new IllegalStateException("Could not find " + interfaceType + " in hierarchy.");
throw new IllegalArgumentException("Could not find " + interfaceType + " in hierarchy.");

Check warning on line 207 in sootup.core/src/main/java/sootup/core/typehierarchy/ViewTypeHierarchy.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/typehierarchy/ViewTypeHierarchy.java#L207

Added line #L207 was not covered by tests
}
if (vertex.type != VertexType.Interface) {
throw new IllegalArgumentException(interfaceType + " is not a class.");
Expand All @@ -228,7 +228,7 @@ public boolean contains(ClassType type) {
public ClassType directSuperClassOf(@Nonnull ClassType classType) {
Vertex vertex = lazyScanResult.get().typeToVertex.get(classType);
if (vertex == null) {
throw new IllegalStateException("Could not find " + classType + " in hierarchy.");
throw new IllegalArgumentException("Could not find " + classType + " in hierarchy.");

Check warning on line 231 in sootup.core/src/main/java/sootup/core/typehierarchy/ViewTypeHierarchy.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/typehierarchy/ViewTypeHierarchy.java#L231

Added line #L231 was not covered by tests
}
Graph<Vertex, Edge> graph = lazyScanResult.get().graph;
List<Vertex> list =
Expand All @@ -241,7 +241,7 @@ public ClassType directSuperClassOf(@Nonnull ClassType classType) {
/* is java.lang.Object */
return null;
} else if (list.size() > 1) {
throw new RuntimeException(classType + "cannot have multiple superclasses");
throw new IllegalArgumentException(classType + "cannot have multiple superclasses");

Check warning on line 244 in sootup.core/src/main/java/sootup/core/typehierarchy/ViewTypeHierarchy.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/typehierarchy/ViewTypeHierarchy.java#L244

Added line #L244 was not covered by tests
} else {
return list.get(0).javaClassType;
}
Expand All @@ -254,7 +254,8 @@ public Set<ClassType> implementedInterfacesOf(@Nonnull ClassType type) {
Vertex vertex = scanResult.typeToVertex.get(type);

if (vertex == null) {
throw new IllegalStateException("Could not find " + type + " in hierarchy for view " + view);
throw new IllegalArgumentException(

Check warning on line 257 in sootup.core/src/main/java/sootup/core/typehierarchy/ViewTypeHierarchy.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/typehierarchy/ViewTypeHierarchy.java#L257

Added line #L257 was not covered by tests
"Could not find " + type + " in hierarchy for view " + view);
}

switch (vertex.type) {
Expand Down Expand Up @@ -300,24 +301,23 @@ private Stream<ClassType> selfAndImplementedInterfaces(Vertex vertex) {
public ClassType superClassOf(@Nonnull ClassType classType) {
final Optional<? extends SootClass<?>> classOpt = view.getClass(classType);
if (!classOpt.isPresent()) {
logger.info("can't get superclass of '" + classType + "' is not in the view.");
return null;
throw new IllegalArgumentException("Could not find '" + classType + "' in the view.");
}
return classOpt.get().getSuperclass().orElse(null);
}

public boolean isInterface(@Nonnull ClassType type) {
Vertex vertex = lazyScanResult.get().typeToVertex.get(type);
if (vertex == null) {
throw new RuntimeException("Could not find '" + type + "' in hierarchy.");
throw new IllegalArgumentException("Could not find '" + type + "' in hierarchy.");

Check warning on line 312 in sootup.core/src/main/java/sootup/core/typehierarchy/ViewTypeHierarchy.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/typehierarchy/ViewTypeHierarchy.java#L312

Added line #L312 was not covered by tests
}
return vertex.type == VertexType.Interface;
}

public boolean isClass(@Nonnull ClassType type) {
Vertex vertex = lazyScanResult.get().typeToVertex.get(type);
if (vertex == null) {
throw new RuntimeException("Could not find '" + type + "' in hierarchy.");
throw new IllegalArgumentException("Could not find '" + type + "' in hierarchy.");

Check warning on line 320 in sootup.core/src/main/java/sootup/core/typehierarchy/ViewTypeHierarchy.java

View check run for this annotation

Codecov / codecov/patch

sootup.core/src/main/java/sootup/core/typehierarchy/ViewTypeHierarchy.java#L320

Added line #L320 was not covered by tests
}
return vertex.type == VertexType.Class;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,12 +228,22 @@ private Set<AncestryPath> buildAncestryPaths(ClassType type) {
}
}
} else {
Set<ClassType> superInterfaces = typeHierarchy.directlyImplementedInterfacesOf(node.type);

Set<ClassType> superInterfaces;
ClassType superClass;
try {
superInterfaces = typeHierarchy.directlyImplementedInterfacesOf(node.type);
superClass = typeHierarchy.superClassOf(node.type);
} catch (IllegalArgumentException iae) {

Check warning on line 237 in sootup.java.bytecode/src/main/java/sootup/java/bytecode/interceptors/typeresolving/BytecodeHierarchy.java

View check run for this annotation

Codecov / codecov/patch

sootup.java.bytecode/src/main/java/sootup/java/bytecode/interceptors/typeresolving/BytecodeHierarchy.java#L237

Added line #L237 was not covered by tests
// node.type does not exist in
continue;

Check warning on line 239 in sootup.java.bytecode/src/main/java/sootup/java/bytecode/interceptors/typeresolving/BytecodeHierarchy.java

View check run for this annotation

Codecov / codecov/patch

sootup.java.bytecode/src/main/java/sootup/java/bytecode/interceptors/typeresolving/BytecodeHierarchy.java#L239

Added line #L239 was not covered by tests
}

for (ClassType superInterface : superInterfaces) {
AncestryPath superNode = new AncestryPath(superInterface, node);
pathNodes.add(superNode);
}
ClassType superClass = typeHierarchy.superClassOf(node.type);

// only java.lang.Object can have no SuperClass i.e. is null
if (superClass != null) {
AncestryPath superNode = new AncestryPath(superClass, node);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ public class IncompleteSuperclassTest extends JavaTypeHierarchyTestBase {
public void method() {
ViewTypeHierarchy typeHierarchy =
(ViewTypeHierarchy) customTestWatcher.getView().getTypeHierarchy();
List<ClassType> superclasses =
typeHierarchy.incompleteSuperClassesOf(getClassType("SubClassB"));
List<ClassType> superclasses = typeHierarchy.superClassesOf(getClassType("SubClassB"));
ClassType object = getClassType("java.lang.Object");
ImmutableList<ClassType> expectedSuperClasses =
immutableList(getClassType("SubClassA"), object);
Expand Down

0 comments on commit cc8a35a

Please sign in to comment.