Commit 81c8d7b2 authored by Carlos Galindo's avatar Carlos Galindo
Browse files

Fix: only a single method is possible when using super.call()

- Previously, all types were considered possible. In reality, only a single method can be called (the first parent class that defines it).
parent 40a0816c
Loading
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -214,8 +214,11 @@ public class CallGraph extends DirectedPseudograph<CallGraph.Vertex, CallGraph.E
                } else if (scope.get().isThisExpr()) {
                    // c) 'ClassName.this', the given class and any subclass
                    dynamicTypes = classGraph.subclassesOf(scope.get().asThisExpr().resolve().asClass());
                } else if (scope.get().isSuperExpr()) {
                    // d) 'super': start with the parent type and get the first implementation
                    dynamicTypes = Set.of(classGraph.parentOf(typeStack.peek()).orElseThrow());
                } else {
                    // d) others: compute possible dynamic types of the expression (TODO)
                    // e) others: compute possible dynamic types of the expression (TODO)
                    dynamicTypes = classGraph.subclassesOf(scope.get().calculateResolvedType().asReferenceType());
                }
                // Locate the corresponding methods for each possible dynamic type, they must be available to all
+10 −0
Original line number Diff line number Diff line
@@ -159,6 +159,16 @@ public class ClassGraph extends DirectedPseudograph<ClassGraph.Vertex<?>, ClassG
                .findFirst();
    }

    public Optional<? extends TypeDeclaration<?>> parentOf(TypeDeclaration<?> declaration) {
        return incomingEdgesOf(findClassVertex(declaration)).stream()
                .filter(ClassArc.Extends.class::isInstance)
                .map(this::getEdgeSource)
                .map(Vertex::getDeclaration)
                .filter(BodyDeclaration::isTypeDeclaration)
                .map(bd -> (TypeDeclaration<?>) bd)
                .findFirst();
    }

    public Optional<ObjectTree> generateObjectTreeForReturnOf(CallableDeclaration<?> callableDeclaration) {
        if (callableDeclaration.isMethodDeclaration()) {
            MethodDeclaration method = callableDeclaration.asMethodDeclaration();