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.SemanticException;
import polyglot.types.TypeSystem;
import polyglot.util.InternalCompilerError;
import accrue.AccrueScheduler;
import accrue.analysis.pointer.RegisterPointerStmtsVisitor;

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

    protected RegisterPointerStmtsGoal(Job job, TypeSystem ts, NodeFactory nf) {
        super(job, new RegisterPointerStmtsVisitor(job, ts, nf));

        // force the loading of some classes used by this analysis

        ts.Object();
        ts.Class();
        ts.String();
        ts.Throwable();
        try {
            ts.typeForName("java.lang.Error");
            ts.typeForName("java.lang.Exception");
            ts.typeForName("java.lang.RuntimeException");
            ts.typeForName("java.lang.Cloneable");
            ts.typeForName("java.io.Serializable");
            ts.typeForName("java.lang.NullPointerException");
            ts.typeForName("java.lang.ClassCastException");
            ts.typeForName("java.lang.ArrayIndexOutOfBoundsException");
            ts.typeForName("java.lang.ArrayStoreException");
            ts.typeForName("java.lang.ArithmeticException");
        }
        catch (SemanticException e) {
            throw new InternalCompilerError("Couldn't find an expected class",
                                            e);
        }

    }

    @Override
    public Collection<Goal> prerequisiteGoals(Scheduler scheduler) {
        List<Goal> l = new ArrayList<Goal>();
        l.add(((AccrueScheduler) scheduler).helper().PostModificationGoal(job));

        l.addAll(super.prerequisiteGoals(scheduler));
        return l;
    }
}
