package accrue.analysis.domination;

import java.util.HashMap;
import java.util.Map;

import polyglot.frontend.ExtensionInfo;
import polyglot.frontend.goals.Goal;
import polyglot.util.Pair;
import accrue.AccrueExtensionInfo;
import accrue.analysis.goals.RegisterProceduresGoal;
import accrue.analysis.interprocanalysis.AnalysisFactory;
import accrue.analysis.interprocanalysis.InterProcAnalysisPass;
import accrue.analysis.interprocanalysis.Registrar;
import accrue.analysis.interprocanalysis.Unit;

public class DominationPass extends InterProcAnalysisPass<Unit> {

    public enum Kind {
        DOMINATION, POSTDOMINATION, NONFATALPOSTDOMINATION
    };

    public static final String ANALYSIS_RESULT_IMMED_POST_DOMINATOR_OF =
            "accrue.analysis.domination.POST_DOMINATOR_OF";
    public static final String ANALYSIS_RESULT_IMMED_POST_DOMINATED_BY =
            "accrue.analysis.domination.POST_DOMINATED_BY";
    public static final String ANALYSIS_RESULT_IMMED_DOMINATOR_OF =
            "accrue.analysis.domination.DOMINATOR_OF";
    public static final String ANALYSIS_RESULT_IMMED_DOMINATED_BY =
            "accrue.analysis.domination.DOMINATED_BY";

    static private Map<Pair<AccrueExtensionInfo, Kind>, DominationPass> singletons =
            new HashMap<Pair<AccrueExtensionInfo, Kind>, DominationPass>();

    static public DominationPass singleton(AccrueExtensionInfo extInfo,
            Kind kind, Goal g) {
        Pair<AccrueExtensionInfo, Kind> key =
                new Pair<AccrueExtensionInfo, Kind>(extInfo, kind);
        DominationPass singleton = singletons.get(key);
        if (singleton == null) {
            singleton =
                    new DominationPass(extInfo,
                                       kind,
                                       g,
                                       RegisterProceduresGoal.registrar(extInfo),
                                       new DominationAnalysisFactory(kind,
                                                                     extInfo));
            singletons.put(key, singleton);
        }
        return singleton;
    }

    public final Kind kind;

    private DominationPass(ExtensionInfo extInfo, Kind kind, Goal g,
            Registrar registrar, AnalysisFactory<Unit> analysisFactory) {
        super(extInfo, g, registrar, analysisFactory);
        this.kind = kind;
    }
}
