Skip to content
PDGBuilder.java 2.18 KiB
Newer Older
package tfm.graphs;
Javier Costa's avatar
Javier Costa committed

import com.github.javaparser.ast.body.MethodDeclaration;
Javier Costa's avatar
Javier Costa committed
import com.github.javaparser.ast.stmt.BlockStmt;
import tfm.visitors.pdg.ControlDependencyBuilder;
import tfm.visitors.pdg.DataDependencyBuilder;
Javier Costa's avatar
Javier Costa committed

 * Populates a {@link PDG}, given a complete {@link CFG}, an empty {@link PDG} and an AST root node.
 * For now it only accepts {@link MethodDeclaration} as root, as it can only receive a single CFG.
 * <br/>
 * <b>Usage:</b>
 * <ol>
 *     <li>Create an empty {@link CFG}.</li>
 *     <li>Create an empty {@link PDG} (optionally passing the {@link CFG} as argument).</li>
 *     <li>Create a new {@link PDGBuilder}, passing both graphs as arguments.</li>
 *     <li>Accept the builder as a visitor of the {@link MethodDeclaration} you want to analyse using
 *     {@link com.github.javaparser.ast.Node#accept(com.github.javaparser.ast.visitor.VoidVisitor, Object) Node#accept(VoidVisitor, Object)}:
 *     {@code methodDecl.accept(builder, null)}</li>
 *     <li>Once the previous step is finished, the complete PDG is saved in
 *     the object created in the second step. The builder should be discarded
 *     and not reused.</li>
 * </ol>
 */
public class PDGBuilder {
    private PDG pdg;
    private CFG cfg;
Javier Costa's avatar
Javier Costa committed

    protected PDGBuilder(PDG pdg) {
        assert pdg.getCfg() != null;
        this.pdg = pdg;
        this.cfg = pdg.getCfg();
Javier Costa's avatar
Javier Costa committed
    }

    public void createFrom(MethodDeclaration methodDeclaration) {
        if (!methodDeclaration.getBody().isPresent())
            throw new IllegalStateException("Method needs to have a body");

        this.pdg.buildRootNode("ENTER " + methodDeclaration.getNameAsString(), methodDeclaration);
Javier Costa's avatar
Javier Costa committed

        assert this.pdg.getRootNode().isPresent();
Javier Costa's avatar
Javier Costa committed

Javier Costa's avatar
Javier Costa committed
        BlockStmt methodBody = methodDeclaration.getBody().get();

        // build CFG
        cfg.build(methodDeclaration);
Javier Costa's avatar
Javier Costa committed

        // Build control dependency
        ControlDependencyBuilder controlDependencyBuilder = new ControlDependencyBuilder(pdg, cfg);
        controlDependencyBuilder.analyze();
Javier Costa's avatar
Javier Costa committed

        // Build data dependency
        DataDependencyBuilder dataDependencyBuilder = new DataDependencyBuilder(pdg, cfg);
        methodBody.accept(dataDependencyBuilder, null);
Javier Costa's avatar
Javier Costa committed
    }
Javier Costa's avatar
Javier Costa committed
}