package org.scribble.ast; import java.util.Iterator; import org.antlr.runtime.tree.CommonTree; import org.scribble.ast.context.ModuleContext; import org.scribble.ast.name.qualified.ProtocolNameNode; import org.scribble.main.JobContext; import org.scribble.main.ScribbleException; import org.scribble.sesstype.kind.ProtocolKind; import org.scribble.sesstype.name.ProtocolName; import org.scribble.sesstype.name.Role; import org.scribble.visit.AstVisitor; public abstract class Do<K extends ProtocolKind> extends SimpleInteractionNode<K> //implements ScopedNode { //public final ScopeNode scope; public final RoleArgList roles; public final NonRoleArgList args; public final ProtocolNameNode<K> proto; // Maybe use an "Ambiguous" version until names resolved -- is a visible protocol, but not necessarily a simple or full member name protected Do(CommonTree source, RoleArgList roleinstans, NonRoleArgList arginstans, ProtocolNameNode<K> proto) { super(source); //this.scope = scope; this.roles = roleinstans; this.args = arginstans; this.proto = proto; } public abstract Do<K> reconstruct(RoleArgList roleinstans, NonRoleArgList arginstans, ProtocolNameNode<K> proto); public abstract ProtocolNameNode<K> getProtocolNameNode(); @Override public Do<K> visitChildren(AstVisitor nv) throws ScribbleException { //ScopeNode scope = isScoped() ? (ScopeNode) visitChild(this.scope, nv) : null; RoleArgList ril = (RoleArgList) visitChild(this.roles, nv); NonRoleArgList al = (NonRoleArgList) visitChild(this.args, nv); ProtocolNameNode<K> proto = visitChildWithClassEqualityCheck(this, this.proto, nv); return reconstruct(ril, al, proto); } // FIXME: mcontext now redundant because NameDisambiguator converts all targets to full names // To get full name from original target name, use mcontext visible names (e.g. in or before name disambiguation pass) // This is still useful for subclass casting to G/LProtocolName public ProtocolName<K> getTargetProtocolDeclFullName(ModuleContext mcontext) { //return mcontext.checkProtocolDeclDependencyFullName(this.proto.toName()); return this.proto.toName(); // Pre: use after name disambiguation (maybe drop FullName suffix) } // mcontext redundant because redundant for getTargetProtocolDeclFullName public ProtocolDecl<K> getTargetProtocolDecl(JobContext jcontext, ModuleContext mcontext) { ProtocolName<K> fullname = getTargetProtocolDeclFullName(mcontext); return jcontext.getModule(fullname.getPrefix()).getProtocolDecl(fullname.getSimpleName()); } public Role getTargetRoleParameter(JobContext jcontext, ModuleContext mcontext, Role role) { Iterator<Role> args = this.roles.getRoles().iterator(); Iterator<Role> params = getTargetProtocolDecl(jcontext, mcontext).header.roledecls.getRoles().iterator(); while (args.hasNext()) { Role arg = args.next(); Role param = params.next(); if (arg.equals(role)) { return param; } } throw new RuntimeException("Not an argument role: " + role); } /*@Override public boolean isEmptyScope() { return this.scope == null; } @Override //public Scope getScope() public SimpleName getScopeElement() { return this.scope.toName(); } public boolean isScoped() { return this.scope != null; }*/ @Override public String toString() { String s = Constants.DO_KW + " "; //if (!hasEmptyScopeNode()) /*if (isScoped()) { s += this.scope + ":"; }*/ return s + this.proto + this.args + this.roles + ";"; } }