/**
 * 
 */
package accrue.analysis.pointer;

import java.util.Set;

import polyglot.main.Report;
import polyglot.types.CodeInstance;
import polyglot.types.Type;
import polyglot.util.Position;
import accrue.analysis.AnalysisTopics;
import accrue.analysis.pointer.PointsToEngine.StmtAndContext;
import accrue.analysis.pointer.analyses.HeapAbstractionFactory;

/**
 * left = right, but only allow left to point to objects that
 * are subtypes ot t and are not subtypes of any element of notT. 
 */
public class StmtFilteredLocalToLocal extends PointsToStmt {
    final ReferenceVariable left;
    final ReferenceVariable right;
    final Type t;
    final Set<Type> notT;

    public StmtFilteredLocalToLocal(ReferenceVariable left, ReferenceVariable right, Type t,
            Set<Type> notT, Position origin, CodeInstance code) {
        super(origin, code, left.expectedType(), t, false);
        this.left = left;
        this.right = right;
        this.t = t;
        this.notT = notT;
    }

    @Override
    public String toString() {
        return left + " = " + right;
    }

    @Override
    public boolean process(CContext context, PointsToGraph g,
            StmtRegistrar registrar, HeapAbstractionFactory af,
            StmtAndContext sac) {
        PointsToGraphNode l =
                ReferenceVariableReplica.create(context, left, af);
        PointsToGraphNode r =
                ReferenceVariableReplica.create(context, right, af);

        if (Report.should_report(AnalysisTopics.POINTSTO, 3))
            Report.report(3, "Processing filtered local to local " + this
                    + " in context " + context);

        return g.addEdges(sac, l, g.pointsToFiltered(sac, r, t, notT), origin);
    }

}
