package org.scribble.del;
import org.scribble.ast.AstFactoryImpl;
import org.scribble.ast.Do;
import org.scribble.ast.ScribNode;
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.SubprotocolSig;
import org.scribble.sesstype.kind.ProtocolKind;
import org.scribble.sesstype.name.ProtocolName;
import org.scribble.sesstype.name.Role;
import org.scribble.visit.ProtocolDefInliner;
import org.scribble.visit.context.ProtocolDeclContextBuilder;
import org.scribble.visit.wf.NameDisambiguator;
public abstract class DoDel extends SimpleInteractionNodeDel
{
public DoDel()
{
}
@Override
public void enterDisambiguation(ScribNode parent, ScribNode child, NameDisambiguator disamb) throws ScribbleException
{
ModuleContext mc = disamb.getModuleContext();
Do<?> doo = (Do<?>) child;
ProtocolName<?> simpname = doo.proto.toName();
if (!mc.isVisibleProtocolDeclName(simpname)) // FIXME: do on entry here, before visiting DoArgListDel
{
throw new ScribbleException(doo.proto.getSource(), "Protocol decl not visible: " + simpname);
}
}
@Override
public ScribNode leaveDisambiguation(ScribNode parent, ScribNode child, NameDisambiguator disamb, ScribNode visited) throws ScribbleException
{
return leaveDisambiguationAux(parent, child, disamb, visited); // To introduce type parameter
}
// Convert all visible names to full names for protocol inlining: otherwise could get clashes if directly inlining external visible names under the root modulecontext
// Not done in G/LProtocolNameNodeDel because it's only for do-targets that this is needed (cf. ProtocolHeader)
private <K extends ProtocolKind> ScribNode
leaveDisambiguationAux(ScribNode parent, ScribNode child, NameDisambiguator disamb, ScribNode visited)
throws ScribbleException
{
@SuppressWarnings("unchecked") // Doesn't matter what K is, just need to propagate it down
Do<K> doo = (Do<K>) visited;
ModuleContext mc = disamb.getModuleContext();
ProtocolName<K> fullname = mc.getVisibleProtocolDeclFullName(doo.proto.toName());
ProtocolNameNode<K> pnn = (ProtocolNameNode<K>)
AstFactoryImpl.FACTORY.QualifiedNameNode(doo.proto.getSource(), fullname.getKind(), fullname.getElements());
// Didn't keep original namenode del
return doo.reconstruct(doo.roles, doo.args, pnn);
}
@Override
public Do<?> leaveProtocolDeclContextBuilding(ScribNode parent, ScribNode child, ProtocolDeclContextBuilder builder, ScribNode visited) throws ScribbleException
{
JobContext jcontext = builder.job.getContext();
ModuleContext mcontext = builder.getModuleContext();
Do<?> doo = (Do<?>) visited;
ProtocolName<?> pn = doo.proto.toName(); // leaveDisambiguation has fully qualified the target name
doo.roles.getRoles().forEach((r) -> addProtocolDependency(builder, r, pn, doo.getTargetRoleParameter(jcontext, mcontext, r)));
return doo;
}
protected abstract void addProtocolDependency(ProtocolDeclContextBuilder builder, Role self, ProtocolName<?> proto, Role target);
@Override
public void enterProtocolInlining(ScribNode parent, ScribNode child, ProtocolDefInliner inl) throws ScribbleException
{
super.enterProtocolInlining(parent, child, inl);
if (!inl.isCycle())
{
SubprotocolSig subsig = inl.peekStack(); // SubprotocolVisitor has already entered subprotocol
inl.setSubprotocolRecVar(subsig);
}
}
}