package accrue.analysis.ext;

import java.util.LinkedHashMap;
import java.util.Map;

import polyglot.ast.Formal;
import polyglot.util.InternalCompilerError;
import polyglot.util.SerialVersionUID;
import polyglot.visit.DataFlow;
import polyglot.visit.FlowGraph;
import polyglot.visit.FlowGraph.EdgeKey;
import polyglot.visit.FlowGraph.Peer;
import accrue.analysis.interprocanalysis.DataFlowDispatch;
import accrue.analysis.pointer.ConstructorContext;
import accrue.analysis.pointer.ReferenceVariable;

public class ExtFormal extends ExtTerm {
    private static final long serialVersionUID = SerialVersionUID.generate();

    private Map<ConstructorContext, ReferenceVariable> referenceVariables;
    private boolean isCatchFormal = false;

    public void setIsCatchFormal() {
        this.isCatchFormal = true;
    }

    public boolean isCatchFormal() {
        return this.isCatchFormal;
    }

    public void setReferenceVariable(ReferenceVariable node,
            ConstructorContext constructorContext) {
        if (this.referenceVariables == null) {
            referenceVariables = new LinkedHashMap<ConstructorContext, ReferenceVariable>();
        }
        if (referenceVariables.containsKey(constructorContext)) {
            throw new InternalCompilerError("Nodes should only be set once for each constructorContext! constructorContext is "
                    + constructorContext + " formal is " + this.node());
        }
//        else {        	
//        	Thread.dumpStack();
//        }
        this.referenceVariables.put(constructorContext, node);
    }

    public ReferenceVariable getReferenceVariable(ConstructorContext constructorContext) {
        if (this.referenceVariables == null) {
            return null;
        }
        return referenceVariables.get(constructorContext);
    }

    @Override
    public <DFItem extends DataFlow.Item> Map<EdgeKey, DFItem> flowDispatch(
            DataFlowDispatch<DFItem> dataflow, DFItem dfIn,
            FlowGraph<DFItem> graph, Peer<DFItem> peer) {
        Formal n = (Formal) this.node();
        return dataflow.flowFormal(n, dfIn, graph, peer);
    }

}
