package accrue.analysis.defuse;

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

import polyglot.frontend.ExtensionInfo;
import accrue.AccrueExtensionInfo;
import accrue.analysis.defuse.DefUseAnalysisUtil.Mode;
import accrue.analysis.goals.RegisterProceduresGoal;
import accrue.analysis.interprocanalysis.Registrar;
import accrue.analysis.interprocvarcontext.InterProcVarContextPass;

public class DefUsePass extends InterProcVarContextPass<DefUseAbsVal> {

    static private Map<ExtensionInfo, DefUsePass> intraSingletons =
            new HashMap<ExtensionInfo, DefUsePass>();

    static private Map<ExtensionInfo, DefUsePass> interSingletons =
            new HashMap<ExtensionInfo, DefUsePass>();

    static public DefUsePass singleton(AccrueExtensionInfo extInfo, Mode mode) {
        Map<ExtensionInfo, DefUsePass> singletons;
        switch (mode) {
        case INTER_EDGES:
            singletons = interSingletons;
            break;
        case INTRA_EDGES:
            singletons = intraSingletons;
            break;
        default:
            throw new Error("Unknown mode " + mode);
        }
        DefUsePass singleton = singletons.get(extInfo);
        if (singleton == null) {
            singleton =
                    new DefUsePass(extInfo,
                                   RegisterProceduresGoal.registrar(extInfo),
                                   new DefUseAnalysisFactory(extInfo,
                                                             mode,
                                                             false), mode);
            singletons.put(extInfo, singleton);
        }
        return singleton;
    }

    private DefUsePass(ExtensionInfo extInfo, Registrar registrar,
            DefUseAnalysisFactory analysisFactory, Mode mode) {
        super(extInfo,
              DefUseGoal.singleton(extInfo, mode),
              registrar,
              analysisFactory);
    }
}
