diff --git a/sootup.callgraph/src/main/java/sootup/callgraph/AbstractCallGraphAlgorithm.java b/sootup.callgraph/src/main/java/sootup/callgraph/AbstractCallGraphAlgorithm.java index 7ab1607c983..b07da6e1747 100644 --- a/sootup.callgraph/src/main/java/sootup/callgraph/AbstractCallGraphAlgorithm.java +++ b/sootup.callgraph/src/main/java/sootup/callgraph/AbstractCallGraphAlgorithm.java @@ -313,16 +313,21 @@ protected abstract void postProcessingMethod( @Nonnull @Override public CallGraph addClass(@Nonnull CallGraph oldCallGraph, @Nonnull JavaClassType classType) { - MutableCallGraph updated = oldCallGraph.copy(); - SootClass clazz = view.getClassOrThrow(classType); Set newMethodSignatures = - clazz.getMethods().stream().map(Method::getSignature).collect(Collectors.toSet()); + clazz.getMethods().stream() + .map(Method::getSignature) + .filter(methodSig -> !oldCallGraph.containsMethod(methodSig)) + .collect(Collectors.toSet()); - if (newMethodSignatures.stream().anyMatch(oldCallGraph::containsMethod)) { - throw new IllegalArgumentException("CallGraph already contains methods from " + classType); + // were all the added method signatures already visited in the CallGraph? i.e. is there + // something to add? + if (newMethodSignatures.isEmpty()) { + return oldCallGraph; } + MutableCallGraph updated = oldCallGraph.copy(); + // Step 1: Add edges from the new methods to other methods Deque workList = new ArrayDeque<>(newMethodSignatures); Set processed = new HashSet<>(oldCallGraph.getMethodSignatures()); @@ -354,8 +359,10 @@ public CallGraph addClass(@Nonnull CallGraph oldCallGraph, @Nonnull JavaClassTyp MethodSignature overridingMethodSig = clazz.getMethod(overriddenMethodSig.getSubSignature()).get().getSignature(); - for (MethodSignature callingMethodSig : updated.callsTo(overriddenMethodSig)) { - updated.addCall(callingMethodSig, overridingMethodSig); + if (updated.containsMethod(overriddenMethodSig)) { + for (MethodSignature callingMethodSig : updated.callsTo(overriddenMethodSig)) { + updated.addCall(callingMethodSig, overridingMethodSig); + } } }); diff --git a/sootup.java.core/src/main/java/sootup/java/core/JavaSootClass.java b/sootup.java.core/src/main/java/sootup/java/core/JavaSootClass.java index c4ed4b40049..a4962269df4 100644 --- a/sootup.java.core/src/main/java/sootup/java/core/JavaSootClass.java +++ b/sootup.java.core/src/main/java/sootup/java/core/JavaSootClass.java @@ -37,6 +37,7 @@ import sootup.core.signatures.MethodSubSignature; import sootup.core.types.ClassType; import sootup.core.types.Type; +import sootup.java.core.types.JavaClassType; import sootup.java.core.views.JavaView; public class JavaSootClass extends SootClass { @@ -45,6 +46,12 @@ public JavaSootClass(JavaSootClassSource classSource, SourceType sourceType) { super(classSource, sourceType); } + @Nonnull + @Override + public JavaClassType getType() { + return (JavaClassType) super.getType(); + } + /** * Get all annotations on this class. If provided with a View, will also resolve all inherited * annotations from super classes.