package accrue.analysis.goals;

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

import polyglot.ast.NodeFactory;
import polyglot.frontend.Job;
import polyglot.frontend.Scheduler;
import polyglot.frontend.goals.Goal;
import polyglot.frontend.goals.VisitorGoal;
import polyglot.types.TypeSystem;
import accrue.AccrueOptions;
import accrue.AccrueScheduler;
import accrue.analysis.visit.SimplifyExpressions;

public class SimplifyExpressionsGoal extends VisitorGoal {
    public static Goal create(Scheduler scheduler, Job job, NodeFactory nf,
            TypeSystem ts) {
        return scheduler.internGoal(new SimplifyExpressionsGoal(job, nf, ts));
    }

    protected SimplifyExpressionsGoal(Job job, NodeFactory nf, TypeSystem ts) {
        super(job, new SimplifyExpressions(nf, ts));
    }

    @Override
    public Collection<Goal> prerequisiteGoals(Scheduler scheduler) {
        List<Goal> l = new ArrayList<Goal>();
        l.add(scheduler.ReachabilityChecked(job));
        l.add(scheduler.ConstantsChecked(job));
        l.add(scheduler.ExceptionsChecked(job));
        l.add(scheduler.ExitPathsChecked(job));
        l.add(scheduler.InitializationsChecked(job));
        l.add(scheduler.ConstructorCallsChecked(job));
        l.add(scheduler.ForwardReferencesChecked(job));

        if (((AccrueOptions) this.job().extensionInfo().getOptions()).helper().flattenExpressions) {
            l.add(((AccrueScheduler) scheduler).helper()
                                               .ExpressionFlattenerGoal(job));
        }

        l.add(((AccrueScheduler) scheduler).helper().MoveInnerClassesGoal(job));
        l.add(((AccrueScheduler) scheduler).helper().MoveLocalClassesGoal(job));
        l.add(((AccrueScheduler) scheduler).helper()
                                           .MakeTargetsExplicitGoal(job));
        return l;
    }
}
