package org.scribble.del; import java.util.Set; import org.scribble.ast.Module; import org.scribble.ast.ProtocolDecl; import org.scribble.ast.ScribNode; import org.scribble.ast.context.ProtocolDeclContext; import org.scribble.main.ScribbleException; import org.scribble.sesstype.SubprotocolSig; import org.scribble.sesstype.kind.ProtocolKind; import org.scribble.sesstype.name.MemberName; 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.util.RoleCollector; import org.scribble.visit.wf.NameDisambiguator; public abstract class ProtocolDeclDel<K extends ProtocolKind> extends ScribDelBase { private ProtocolDeclContext<K> pdcontext; protected ProtocolDeclDel() { } protected abstract ProtocolDeclDel<K> copy(); @Override public ScribNode leaveDisambiguation(ScribNode parent, ScribNode child, NameDisambiguator disamb, ScribNode visited) throws ScribbleException { disamb.clear(); return visited; } @Override public void enterProtocolDeclContextBuilding(ScribNode parent, ScribNode child, ProtocolDeclContextBuilder builder) throws ScribbleException { builder.clearProtocolDependencies(); // collect per protocoldecl all together, do not clear? Module main = (Module) parent; ProtocolDecl<?> pd = (ProtocolDecl<?>) child; MemberName<?> pn = pd.getFullMemberName(main); // Is it really needed to add self protocoldecl dependencies? pd.header.roledecls.getRoles().stream().forEach((r) -> addSelfDependency(builder, (ProtocolName<?>) pn, r)); } protected abstract void addSelfDependency(ProtocolDeclContextBuilder builder, ProtocolName<?> proto, Role role); @Override public void enterProtocolInlining(ScribNode parent, ScribNode child, ProtocolDefInliner inl) throws ScribbleException { SubprotocolSig subsig = inl.peekStack(); // SubprotocolVisitor has already entered subprotocol inl.setSubprotocolRecVar(subsig); } @Override public ScribNode leaveProtocolInlining(ScribNode parent, ScribNode child, ProtocolDefInliner inl, ScribNode visited) throws ScribbleException { return visited; } @Override public ScribNode leaveRoleCollection(ScribNode parent, ScribNode child, RoleCollector coll, ScribNode visited) throws ScribbleException { ProtocolDecl<?> pd = (ProtocolDecl<?>) visited; Set<Role> occs = coll.getNames(); // Needs ProtocolDeclContextBuilder to have built the context already ProtocolDeclDel<K> del = setProtocolDeclContext(getProtocolDeclContext().setRoleOccurrences(occs)); return pd.del(del); } public ProtocolDeclContext<K> getProtocolDeclContext() { return this.pdcontext; } protected ProtocolDeclDel<K> setProtocolDeclContext(ProtocolDeclContext<K> pdcontext) { ProtocolDeclDel<K> copy = copy(); // FIXME: should be a deep clone in principle -- but if any other children are immutable, they can be shared copy.pdcontext = pdcontext; return copy; } }