com.ibm.wala.ide.ui.ViewIFDSLocalAction.java Source code

Java tutorial

Introduction

Here is the source code for com.ibm.wala.ide.ui.ViewIFDSLocalAction.java

Source

/*******************************************************************************
 * Copyright (c) 2002 - 2006 IBM Corporation.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package com.ibm.wala.ide.ui;

import java.util.Iterator;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.viewers.IStructuredSelection;

import com.ibm.wala.dataflow.IFDS.ISupergraph;
import com.ibm.wala.dataflow.IFDS.TabulationResult;
import com.ibm.wala.ipa.cfg.BasicBlockInContext;
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
import com.ibm.wala.ssa.SSAGetInstruction;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.ssa.SSAPhiInstruction;
import com.ibm.wala.ssa.analysis.IExplodedBasicBlock;
import com.ibm.wala.util.WalaException;
import com.ibm.wala.util.Predicate;
import com.ibm.wala.util.debug.Assertions;
import com.ibm.wala.util.graph.Graph;
import com.ibm.wala.util.graph.GraphSlicer;
import com.ibm.wala.viz.DotUtil;
import com.ibm.wala.viz.NodeDecorator;
import com.ibm.wala.viz.PDFViewUtil;

/**
 * An SWT action that spawns spawns a ghostview to see the local supergraph for a procedure node which is the current selection in a
 * tree viewer.
 * 
 * @author sfink
 */
public class ViewIFDSLocalAction<T, P, F> extends Action {
    /**
     * Governing tree viewer
     */
    private final SWTTreeViewer viewer;

    /**
     * Governing supergraph
     */
    private final ISupergraph<T, P> supergraph;

    /**
     * name of PDF file to generate
     */
    private final String pdfFile;

    /**
     * name of dot file to generate
     */
    private final String dotFile;

    /**
     * path to dot.exe
     */
    private final String dotExe;

    /**
     * path to pdf view executable
     */
    private final String pdfViewExe;

    private final NodeDecorator labels;

    public ViewIFDSLocalAction(SWTTreeViewer viewer, TabulationResult<T, P, F> result, String pdfFile,
            String dotFile, String dotExe, String pdfViewExe, NodeDecorator labels) {
        if (result == null) {
            throw new IllegalArgumentException("null result");
        }
        this.viewer = viewer;
        this.supergraph = result.getProblem().getSupergraph();
        this.pdfFile = pdfFile;
        this.dotFile = dotFile;
        this.dotExe = dotExe;
        this.pdfViewExe = pdfViewExe;
        this.labels = labels;
        setText("View Local Supergraph");
    }

    public ViewIFDSLocalAction(SWTTreeViewer viewer, TabulationResult<T, P, F> result, String psFile,
            String dotFile, String dotExe, String gvExe) {
        if (result == null) {
            throw new IllegalArgumentException("null result");
        }
        this.viewer = viewer;
        this.supergraph = result.getProblem().getSupergraph();
        this.pdfFile = psFile;
        this.dotFile = dotFile;
        this.dotExe = dotExe;
        this.pdfViewExe = gvExe;
        this.labels = new Labels<T, P, F>(result);
        setText("View Local Supergraph");
    }

    private static class Labels<T, P, F> implements NodeDecorator {
        private TabulationResult<T, P, F> result;

        Labels(TabulationResult<T, P, F> result) {
            this.result = result;
        }

        @Override
        @SuppressWarnings("unchecked")
        public String getLabel(Object o) throws WalaException {
            T t = (T) o;
            if (t instanceof BasicBlockInContext) {
                BasicBlockInContext bb = (BasicBlockInContext) t;
                if (bb.getDelegate() instanceof IExplodedBasicBlock) {
                    IExplodedBasicBlock delegate = (IExplodedBasicBlock) bb.getDelegate();
                    String s = delegate.getNumber() + " " + result.getResult(t) + "\\n"
                            + stringify(delegate.getInstruction());
                    for (Iterator<SSAPhiInstruction> phis = delegate.iteratePhis(); phis.hasNext();) {
                        SSAPhiInstruction phi = phis.next();
                        s += " " + phi;
                    }
                    if (delegate.isCatchBlock()) {
                        s += " " + delegate.getCatchInstruction();
                    }
                    return s;
                }
            }
            return t + " " + result.getResult(t);
        }
    }

    /**
     * Print a short-ish representation of s as a String
     */
    public static String stringify(SSAInstruction s) {
        if (s == null) {
            return null;
        }
        if (s instanceof SSAAbstractInvokeInstruction) {
            SSAAbstractInvokeInstruction call = (SSAAbstractInvokeInstruction) s;
            String def = call.hasDef() ? Integer.valueOf(call.getDef()) + "=" : "";
            String result = def + "call " + call.getDeclaredTarget().getDeclaringClass().getName().getClassName()
                    + "." + call.getDeclaredTarget().getName();
            result += " exc:" + call.getException();
            for (int i = 0; i < s.getNumberOfUses(); i++) {
                result += " ";
                result += s.getUse(i);
            }
            return result;
        }
        if (s instanceof SSAGetInstruction) {
            SSAGetInstruction g = (SSAGetInstruction) s;
            String fieldName = g.getDeclaredField().getName().toString();

            StringBuffer result = new StringBuffer();
            result.append(g.getDef());
            result.append(":=");
            result.append(g.isStatic() ? "getstatic " : "getfield ");
            result.append(fieldName);
            if (!g.isStatic()) {
                result.append(" ");
                result.append(g.getUse(0));
            }
            return result.toString();
        }
        return s.toString();
    }

    /*
     * @see org.eclipse.jface.action.IAction#run()
     */
    @Override
    public void run() {

        try {
            final P proc = getProcedureForSelection();
            Predicate<T> filter = new Predicate<T>() {
                @Override
                public boolean test(T o) {
                    return supergraph.getProcOf(o).equals(proc);
                }
            };
            Graph<T> localGraph = GraphSlicer.prune(supergraph, filter);

            // spawn the viewer
            System.err.println("Spawn Viewer for " + proc);
            DotUtil.dotify(localGraph, labels, dotFile, pdfFile, dotExe);

            if (DotUtil.getOutputType() == DotUtil.DotOutputType.PDF) {
                PDFViewUtil.launchPDFView(pdfFile, pdfViewExe);
            }
        } catch (WalaException e) {
            e.printStackTrace();
            Assertions.UNREACHABLE();
        }
    }

    @SuppressWarnings("unchecked")
    protected P getProcedureForSelection() {
        // we assume the tree viewer's current selection is a P
        IStructuredSelection selection = viewer.getSelection();
        if (selection.size() != 1) {
            throw new UnsupportedOperationException("did not expect selection of size " + selection.size());
        }
        P first = (P) selection.getFirstElement();

        return first;
    }

    protected SWTTreeViewer getViewer() {
        return viewer;
    }

    protected ISupergraph<T, P> getSupergraph() {
        return supergraph;
    }

    protected String getDotExe() {
        return dotExe;
    }

    protected String getDotFile() {
        return dotFile;
    }

    protected String getGvExe() {
        return pdfViewExe;
    }

    protected String getPsFile() {
        return pdfFile;
    }
}