/* LocalScope - Decompiled by JODE
 * Visit http://jode.sourceforge.net/
 */
package alloy.semantic;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import alloy.ast.Decl;
import alloy.ast.Decls;
import alloy.ast.LeafId;
import alloy.ast.Variable;
import alloy.transform.LeafIdMap;
import alloy.type.RelationType;
import alloy.type.TypeModifier;
import alloy.util.Dbg;

public class LocalScope implements Cloneable
{
    private HashMap _nameToType = new HashMap();
    private ArrayList _parents = new ArrayList();
    
    public static LocalScope genScopeFromDecls(Decls decls) {
	LocalScope localscope = new LocalScope();
	Iterator iterator = decls.getDeclIter();
	while (iterator.hasNext()) {
	    Decl decl = (Decl) iterator.next();
	    RelationType relationtype = decl.getExpr().getType();
	    Iterator iterator_0_ = decl.getVariables().getVariableIter();
	    while (iterator_0_.hasNext()) {
		String string = ((Variable) iterator_0_.next()).nodeString();
		try {
		    localscope.addMapping(string, relationtype);
		} catch (AlreadyMappedException alreadymappedexception) {
		    Dbg.fatal("can't happen");
		}
	    }
	}
	return localscope;
    }
    
    public void addParent(LocalScope localscope_1_) {
	_parents.add(localscope_1_);
    }
    
    public Iterator getParents() {
	return _parents.iterator();
    }
    
    public Iterator getBoundNames() {
	return _nameToType.keySet().iterator();
    }
    
    public LocalScope copy() {
	LocalScope localscope_2_ = null;
	try {
	    localscope_2_ = (LocalScope) this.clone();
	} catch (CloneNotSupportedException clonenotsupportedexception) {
	    /* empty */
	}
	localscope_2_._nameToType = new HashMap(_nameToType);
	localscope_2_._parents = new ArrayList();
	return localscope_2_;
    }
    
    public void addMapping(String string, RelationType relationtype)
	throws AlreadyMappedException {
	Dbg.chk(string != null, "attempt to map null name");
	Dbg.chk(relationtype != null, "attempt to map to null type");
	if (_nameToType.containsKey(string))
	    throw new AlreadyMappedException();
	_nameToType.put(string, relationtype);
    }
    
    public RelationType lookupType(String string) {
	RelationType relationtype = getType(string);
	if (relationtype == null) {
	    Iterator iterator = _parents.iterator();
	    while (iterator.hasNext()) {
		LocalScope localscope_3_ = (LocalScope) iterator.next();
		relationtype = localscope_3_.lookupType(string);
		if (relationtype != null)
		    break;
	    }
	}
	return relationtype;
    }
    
    public LeafIdMap generateLeafIdMapping(LeafIdMap leafidmap) {
	LeafIdMap leafidmap_4_ = new LeafIdMap(leafidmap);
	Iterator iterator = getBoundNames();
	while (iterator.hasNext()) {
	    String string = (String) iterator.next();
	    leafidmap_4_.put(string, new LeafId());
	}
	return leafidmap_4_;
    }
    
    public LocalScope replaceVarTypes(List list, List list_5_) {
	LocalScope localscope_6_ = new LocalScope();
	Dbg.chk(list.size() == list_5_.size(),
		"type lists must have same length");
	HashMap hashmap = new HashMap();
	for (int i = 0; i < list.size(); i++)
	    hashmap.put(list.get(i), list_5_.get(i));
	Iterator iterator = _nameToType.keySet().iterator();
	while (iterator.hasNext()) {
	    String string = (String) iterator.next();
	    Object object = null;
	    RelationType relationtype = getType(string);
	    RelationType relationtype_7_
		= TypeModifier.getModifiedRelationType(relationtype, hashmap);
	    try {
		localscope_6_.addMapping(string, relationtype_7_);
	    } catch (AlreadyMappedException alreadymappedexception) {
		Dbg.fatal("can't happen");
	    }
	}
	return localscope_6_;
    }
    
    private RelationType getType(String string) {
	return (RelationType) _nameToType.get(string);
    }
    
    public String toString() {
	return _nameToType.toString() + " => " + _parents.toString();
    }
}
