Commit 578aad43 authored by Carlos Galindo's avatar Carlos Galindo
Browse files

Fixes based on tests

* Summary arcs are generated correctly for actual-out with multiple actions.
* Properly detect optional actions.
* Fix type insertion at incorrect level in object trees.
* Constructors may throw exceptions.
* Dynamic initializers are marked as implicit.
* The LHS of an operation assignment is included in the ExpressionObjectTreeFinder (e.g. `a += 10`).
* Admit calls from dynamic initializers.
* Removed unused utility methods.
parent 66bc6de4
Loading
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -53,7 +53,7 @@ public class CallGraph extends DirectedPseudograph<CallGraph.Vertex, CallGraph.E
    /** Resolve a call to all its possible declarations, by using the call AST nodes stored on the edges. */
    public Stream<CallableDeclaration<?>> getCallTargets(Resolvable<? extends ResolvedMethodLikeDeclaration> call) {
        return edgeSet().stream()
                .filter(e -> ASTUtils.equalsInDeclaration((Node) e.getCall(), (Node) call))
                .filter(e -> ASTUtils.equalsWithRange(e.getCall(), call))
                .map(this::getEdgeTarget)
                .map(Vertex::getDeclaration)
                .map(decl -> (CallableDeclaration<?>) decl);
@@ -226,6 +226,18 @@ public class CallGraph extends DirectedPseudograph<CallGraph.Vertex, CallGraph.E
            protected void createNormalEdge(CallableDeclaration<?> decl, Resolvable<? extends ResolvedMethodLikeDeclaration> call) {
                addEdge(declStack.peek(), decl, call);
            }

            // Other structures
            @Override
            public void visit(FieldDeclaration n, Void arg) {
                if (declStack.isEmpty() && !n.isStatic()) {
                    for (ConstructorDeclaration cd : classStack.peek().getConstructors()) {
                        declStack.push(cd);
                        super.visit(n, arg);
                        declStack.pop();
                    }
                }
            }
        }, null);
    }

+1 −1
Original line number Diff line number Diff line
@@ -197,7 +197,7 @@ public class ClassGraph extends DirectedPseudograph<ClassGraph.Vertex<?>, ClassG
            for (ClassOrInterfaceDeclaration type : types) {
                Vertex<ClassOrInterfaceDeclaration> subclassVertex = classDeclarationMap.get(mapKey(type));
                if (!findAllFieldsOf(subclassVertex).isEmpty()) {
                    ObjectTree newType = tree.addType(ASTUtils.resolvedTypeDeclarationToResolvedType(type.resolve()));
                    ObjectTree newType = tree.addType(ASTUtils.resolvedTypeDeclarationToResolvedType(type.resolve()), level);
                    generateObjectTreeFor(subclassVertex, tree, level + '.' + newType.getMemberNode().getLabel(), depth);
                }
            }
+5 −2
Original line number Diff line number Diff line
@@ -98,8 +98,11 @@ public class ExpressionObjectTreeFinder {
    public void handleAssignExpr(AssignExpr assignExpr, VariableAction assignTarget, String targetMember) {
        ClassGraph.getInstance().generateObjectTreeForType(assignExpr.getTarget().calculateResolvedType())
                .ifPresent(fields -> assignTarget.getObjectTree().addAll(fields));
        locateExpressionResultTrees(assignExpr.getValue())
                .forEach(pair -> markTransference(pair, assignTarget, targetMember));
        List<Pair<VariableAction, String>> list = new LinkedList<>();
        if (assignExpr.getOperator() != AssignExpr.Operator.ASSIGN)
            list.addAll(locateExpressionResultTrees(assignExpr.getTarget()));
        list.addAll(locateExpressionResultTrees(assignExpr.getValue()));
        list.forEach(pair -> markTransference(pair, assignTarget, targetMember));
    }

    /** Prepares the connection between the right-hand side of the assignment and the GraphNode
+2 −0
Original line number Diff line number Diff line
@@ -252,8 +252,10 @@ public class ESCFG extends ACFG {

        @Override
        public void visit(ExplicitConstructorInvocationStmt n, Void arg) {
            stmtStack.push(n);
            connectTo(n);
            visitCallForExceptions(n);
            stmtStack.pop();
        }

        /** Process a call that may throw exceptions. Generates normal and return nodes, and
+6 −0
Original line number Diff line number Diff line
@@ -47,6 +47,10 @@ public class JSysCFG extends ESCFG {
        builder.implicitDeclaration = implicitConstructors.contains(declaration);
        builder.classGraph = classGraph;
        declaration.accept(builder, null);
        vertexSet().stream()
                .filter(Predicate.not(GraphNode::isImplicitInstruction))
                .filter(gn -> builder.methodInsertedInstructions.contains(gn.getAstNode()))
                .forEach(GraphNode::markAsImplicit);
        // Verify that it has been built
        exitNode = vertexSet().stream().filter(MethodExitNode.class::isInstance).findFirst()
                .orElseThrow(() -> new IllegalStateException("Built graph has no exit node!"));
@@ -188,6 +192,7 @@ public class JSysCFG extends ESCFG {

        @Override
        public void visit(ExplicitConstructorInvocationStmt n, Void arg) {
            stmtStack.push(n);
            // 1. Connect to the following statements
            connectTo(n);
            // 2. Insert dynamic class code (only for super())
@@ -196,6 +201,7 @@ public class JSysCFG extends ESCFG {
                        .forEach(node -> node.accept(this, arg));
            // 3. Handle exceptions
            super.visitCallForExceptions(n);
            stmtStack.pop();
        }

        @Override
Loading