package org.scribble.visit.context; import java.util.Deque; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import org.scribble.ast.ScribNode; import org.scribble.main.Job; import org.scribble.main.ScribbleException; import org.scribble.sesstype.name.RecVar; import org.scribble.sesstype.name.Role; public class ProjectedChoiceSubjectFixer extends ModuleContextVisitor { private Map<RecVar, Deque<Role>> recs = new HashMap<RecVar, Deque<Role>>(); public ProjectedChoiceSubjectFixer(Job job) { super(job); } @Override protected final void enter(ScribNode parent, ScribNode child) throws ScribbleException { super.enter(parent, child); child.del().enterProjectedChoiceSubjectFixing(parent, child, this); /*if (child instanceof LProtocolDecl) { System.out.println("aaa:\n" + ((LProtocolDecl) child)); }*/ } @Override protected ScribNode leave(ScribNode parent, ScribNode child, ScribNode visited) throws ScribbleException { visited = visited.del().leaveProjectedChoiceSubjectFixing(parent, child, this, visited); return super.leave(parent, child, visited); } public Role getChoiceSubject(RecVar rv) { return this.recs.get(rv).peek(); } public void setChoiceSubject(Role subj) { for (Deque<Role> rs : this.recs.values()) { if (!rs.isEmpty()) // E.g. rec X { ... } rec Y { ... } -- after X, X is still in map but is empty { if (rs.peek() == null) { rs.pop(); rs.push(subj); } } } } public void pushRec(RecVar rv) { Deque<Role> tmp = this.recs.get(rv); if (tmp == null) { tmp = new LinkedList<>(); this.recs.put(rv, tmp); } tmp.push(null); } public void popRec(RecVar rv) { this.recs.get(rv).pop(); } public RecVarRole createRecVarRole(RecVar rv) { return new RecVarRole(rv.toString()); } public boolean isRecVarRole(Role r) { return (r instanceof RecVarRole); } } class RecVarRole extends Role // HACK for unguarded continues -- but not actually needed? { private static final long serialVersionUID = 1L; public RecVarRole(String text) { super(text); } }