package accrue.analysis.callgraph;

import polyglot.ast.ProcedureDecl;
import polyglot.types.SemanticException;
import accrue.AccrueExtensionInfo;
import accrue.analysis.interprocanalysis.AnalysisFactory;
import accrue.analysis.interprocanalysis.AnalysisUnit;
import accrue.analysis.interprocanalysis.AnalysisUtil;
import accrue.analysis.interprocanalysis.WorkQueue;

public class PreciseCallGraphFactory extends AnalysisFactory<PCGAbsVal> {
    public PreciseCallGraphFactory(AccrueExtensionInfo extInfo) {
        super(extInfo);
    }

    public static final String ANALYSIS_NAME = "accrue.analysis.callgraph";

    /**
     * EdgeIdentifiers from call sites to code decls.
     */
    public static final String CALL_TARGETS = ANALYSIS_NAME + ".CALL_TARGETS";

    /**
     * EdgeIdentifiers from code decls to call sites.
     */
    public static final String CALL_SOURCES = ANALYSIS_NAME + ".CALL_SOURCES";

    /**
     * EdgeIdentifiers from return sites (including code blocks that return implicitly) to call sites.
     */
    public static final String RETURN_TARGETS = ANALYSIS_NAME
            + ".RETURN_TARGETS";

    /**
     * EdgeIdentifiers from call sites to return sites, including code blocks that return implicitly.
     */
    public static final String RETURN_SOURCES = ANALYSIS_NAME
            + ".RETURN_SOURCES";

    /**
     * EdgeIdentifiers from throw sites to catch sites.
     */
    public static final String CATCH_TARGETS = ANALYSIS_NAME + ".CATCH_TARGETS";

    /**
     * EdgeIdentifiers from catch sites to throw sites.
     */
    public static final String CATCH_SOURCES = ANALYSIS_NAME + ".CATCH_SOURCES";

    /**
     * EdgeIdentifiers between initializers. There is an EDGE_INIT edge from
     * the constructor call to the first initializer, an edge linking the
     * initializers in order, and an EDGE_INIT edge from the last initializer back to the
     * constructor call.
     */
    public static final String INIT_TARGETS = ANALYSIS_NAME + ".INIT_TARGETS";
    /**
     * Backward edges between initializers.
     */
    public static final String INIT_SOURCES = ANALYSIS_NAME + ".INIT_SOURCES";

    @Override
    public String analysisName() {
        return ANALYSIS_NAME;
    }

    @Override
    public String analysisReportName() {
        return ANALYSIS_NAME;
    }

    @Override
    public PCGAbsVal startItem(AnalysisUtil<PCGAbsVal> autil,
            ProcedureDecl startProc) throws SemanticException {
        // the DFIContext for main(String[] args)
        return PCGAbsVal.EMPTY;
    }

    @Override
    public AnalysisUtil<PCGAbsVal> analysisUtil(WorkQueue<PCGAbsVal> wq,
            AnalysisUnit aunit) {
        return new PreciseCallGraphAnalysisUtil(wq, aunit, extInfo);
    }

}
