package accrue.analysis.interprocvarcontext;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

import polyglot.types.ClassType;
import accrue.AccrueExtensionInfo;
import accrue.analysis.interprocanalysis.AbstractLocation;
import accrue.analysis.interprocanalysis.AnalysisFactory;
import accrue.analysis.interprocanalysis.ExitMap.Key;

public abstract class AnalysisFactoryVarContext<T extends AbstractValue<T>>
        extends AnalysisFactory<VarContext<T>> {

    public AnalysisFactoryVarContext(AccrueExtensionInfo extInfo) {
        super(extInfo);
    }

    public FinalVarContext<T> restoreCallingFrame(FinalVarContext<T> output,
            VarContext<T> input, Set<AbstractLocation> writeLocations) {
        Map<AbstractLocation, T> otherLocs =
                new LinkedHashMap<AbstractLocation, T>(input.locations());
        otherLocs.keySet().removeAll(writeLocations);

        return output.modifyAllLocationDomains(writeLocations, otherLocs);
    }

    public abstract T bottomAbstractValue();

    private FinalVarContext<T> EMPTY =
            new FinalVarContext<T>(Collections.<Key, VarContext<T>> emptyMap(),
                                   Collections.<ClassType> emptySet());

    @Override
    public FinalVarContext<T> emptyExitMap() {
        return EMPTY;
    }
}
