/**
 * 
 */
package accrue.analysis.defuse;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import polyglot.frontend.ExtensionInfo;
import polyglot.frontend.Pass;
import polyglot.frontend.Scheduler;
import polyglot.frontend.goals.AbstractGoal;
import polyglot.frontend.goals.Goal;
import accrue.AccrueExtensionInfo;
import accrue.AccrueScheduler;

public class DefUseGoal extends AbstractGoal {
    public static Goal singleton(ExtensionInfo extInfo,
            DefUseAnalysisUtil.Mode mode) {
        Scheduler scheduler = extInfo.scheduler();
        return scheduler.internGoal(new DefUseGoal(mode));
    }

    protected final DefUseAnalysisUtil.Mode mode;

    protected DefUseGoal(DefUseAnalysisUtil.Mode mode) {
        super(null, "DefUseGoal_" + mode);
        this.mode = mode;
    }

    @Override
    public Collection<Goal> prerequisiteGoals(Scheduler scheduler) {
        List<Goal> l = new ArrayList<Goal>();
        l.add(((AccrueScheduler) scheduler).helper().RegisterProceduresDone());
        l.add(((AccrueScheduler) scheduler).helper().PointerAnalysis());
        l.add(((AccrueScheduler) scheduler).helper().NotNullAnalysis());
        l.add(((AccrueScheduler) scheduler).helper()
                                           .PreciseExceptionAnalysis(0));
        // INTRA_EDGES mode currently expects that 
        // the INTER_EDGES analysis has already run.
        if (mode.equals(DefUseAnalysisUtil.Mode.INTRA_EDGES))
            l.add(((AccrueScheduler) scheduler).helper().DefUseAnalysis());
        l.addAll(super.prerequisiteGoals(scheduler));
        return l;
    }

    @Override
    public Pass createPass(ExtensionInfo extInfo) {
        return DefUsePass.singleton((AccrueExtensionInfo) extInfo, mode);
    }
}
