package org.scribble.ast; import java.util.List; import java.util.stream.Collectors; import org.antlr.runtime.tree.CommonTree; import org.scribble.ast.name.simple.ScopeNode; import org.scribble.sesstype.kind.ProtocolKind; public abstract class Interruptible<K extends ProtocolKind> extends CompoundInteractionNode<K> implements ScopedNode { public final ScopeNode scope; public final ProtocolBlock<K> block; private final List<? extends Interrupt> interrs; protected Interruptible(CommonTree source, ScopeNode scope, ProtocolBlock<K> block, List<? extends Interrupt> interrs) { super(source); this.scope = scope; this.block = block; this.interrs = interrs; } /*protected abstract Interruptible<T1, T2> reconstruct(CommonTree ct, ScopeNode scope, T1 block, List<T2> interrs, CompoundInteractionNodeContext icontext, Env env); @Override public NodeContextBuilder enterContextBuilding(NodeContextBuilder builder) throws ScribbleException { builder.pushContext(new CompoundInteractionNodeContext()); return builder; } @Override public Interruptible<T1, T2> leaveContextBuilding(NodeContextBuilder builder) throws ScribbleException { CompoundInteractionNodeContext icontext = (CompoundInteractionNodeContext) builder.popContext(); builder.replaceContext(((CompoundInteractionContext) builder.peekContext()).merge(icontext)); icontext = (CompoundInteractionNodeContext) icontext.merge(this.block.getContext()); //return new Interruptible<T1, T2>(this.ct, this.scope, this.block, this.interrs, icontext); return reconstruct(this.ct, this.scope, this.block, this.interrs, icontext, getEnv()); } @Override public Interruptible<T1, T2> leaveWFChoiceCheck(WellFormedChoiceChecker checker) throws ScribbleException { checker.getEnv().leave(this, checker); return this; /*Role src = this.src.toName(); for (Message msg : this.msgs.stream().map((mn) -> mn.toMessage()).collect(Collectors.toList())) { for (Role dest : ((GlobalInterruptContext) getContext()).getDestinations()) { //checker.getEnv().addInterrupt(src, dest, msg); // No: src must be enabled, and if receiver may be enabled by this interrupt then it must also be receiving normally inside the interruptible block System.out.println("2a: " + src + ", " + dest + ", " + msg); checker.getEnv().addMessage(src, dest, msg); } }* / } @Override public Interruptible<T1, T2> leaveReachabilityCheck(ReachabilityChecker checker) throws ScribbleException { checker.getEnv().leave(this, checker); return this; } @Override public Interruptible<T1, T2> visitChildren(NodeVisitor nv) throws ScribbleException { ScopeNode scope = this.scope; if (scope != null) { scope = (ScopeNode) visitChild(this.scope, nv); } //ProtocolBlock<? extends InteractionSequence<? extends InteractionNode>> block = (ProtocolBlock<? extends InteractionSequence<? extends InteractionNode>>) nv.visit(this.block); T1 block = visitChildWithClassCheck(this, this.block, nv); List<T2> interrs = visitChildListWithClassCheck(this, this.interrs, nv); //return new Interruptible<>(this.ct, scope, block, interrs, getContext(), getEnv()); return reconstruct(this.ct, scope, block, interrs, getContext(), getEnv()); } @Override public boolean isEmptyScope() { return false; } @Override //public Scope getScope() public SimpleName getScopeElement() { return this.scope.toName(); }*/ public boolean isScopeNodeImplicit() { return this.scope == null; } @Override public String toString() { String s = Constants.INTERRUPTIBLE_KW + " "; if (!isScopeNodeImplicit()) { s += this.scope + ": "; } s += this.block + " " + Constants.WITH_KW + " {\n"; s += this.interrs.stream().map((i) -> i.toString()).collect(Collectors.joining("\n")) + "\n"; return s + "}"; } }